Java BOOK
Java BOOK
About ............................................................................................................................................... 1
Chapter 1: Getting started with Java Language .......................................................................... 2
Section 1.1: Creating Your First Java Program .......................................................................................................... 2
Chapter 2: Type Conversion .......................................................................................................... 8
Section 2.1: Numeric primitive casting........................................................................................................................ 8
Section 2.2: Basic Numeric Promotion ....................................................................................................................... 8
Section 2.3: Non-numeric primitive casting ................................................................................................................ 8
Section 2.4: Object casting ......................................................................................................................................... 9
Section 2.5: Testing if an object can be cast using instanceof ................................................................................... 9
Chapter 3: Getters and Setters.....................................................................................................10
Section 3.1: Using a setter or getter to implement a constraint ................................................................................10
Section 3.2: Why Use Getters and Setters? .............................................................................................................10
Section 3.3: Adding Getters and Setters ..................................................................................................................11
Chapter 4: Reference Data Types ................................................................................................13
Section 4.1: Dereferencing .......................................................................................................................................13
Section 4.2: Instantiating a reference type ...............................................................................................................13
Chapter 5: Java Compiler - 'javac' ...............................................................................................14
Section 5.1: The 'javac' command - getting started ..................................................................................................14
Section 5.2: Compiling for a di erent version of Java ..............................................................................................16
Chapter 6: Documenting Java Code ............................................................................................18
Section 6.1: Building Javadocs From the Command Line ........................................................................................18
Section 6.2: Class Documentation ............................................................................................................................18
Section 6.3: Method Documentation.........................................................................................................................19
Section 6.4: Package Documentation.......................................................................................................................20
Section 6.5: Links......................................................................................................................................................20
Section 6.6: Code snippets inside documentation ....................................................................................................21
Section 6.7: Field Documentation .............................................................................................................................22
Section 6.8: Inline Code Documentation ..................................................................................................................22
Chapter 7: Command line Argument Processing .......................................................................24
Section 7.1: Argument processing using GWT ToolBase ........................................................................................24
Section 7.2: Processing arguments by hand ............................................................................................................24
Chapter 8: The Java Command - 'java' and 'javaw' ....................................................................27
Section 8.1: Entry point classes ................................................................................................................................27
Section 8.2: Troubleshooting the 'java' command ....................................................................................................27
Section 8.3: Running a Java application with library dependencies .........................................................................29
Section 8.4: Java Options .........................................................................................................................................30
Section 8.5: Spaces and other special characters in arguments .............................................................................31
Section 8.6: Running an executable JAR file ...........................................................................................................33
Section 8.7: Running a Java applications via a "main" class ...................................................................................33
Chapter 9: Literals .........................................................................................................................35
Section 9.1: Using underscore to improve readability ..............................................................................................35
Section 9.2: Hexadecimal, Octal and Binary literals .................................................................................................35
Section 9.3: Boolean literals .....................................................................................................................................36
Section 9.4: String literals .........................................................................................................................................36
Section 9.5: The Null literal .......................................................................................................................................37
Section 9.6: Escape sequences in literals ................................................................................................................37
Section 9.7: Character literals ...................................................................................................................................38
Section 9.8: Decimal Integer literals .........................................................................................................................38
Section 9.9: Floating-point literals.............................................................................................................................39
Chapter 10: Primitive Data Types ................................................................................................42
Section 10.1: The char primitive ...............................................................................................................................42
Section 10.2: Primitive Types Cheatsheet ................................................................................................................42
Section 10.3: The float primitive ...............................................................................................................................43
Section 10.4: The int primitive ..................................................................................................................................44
Section 10.5: Converting Primitives ..........................................................................................................................45
Section 10.6: Memory consumption of primitives vs. boxed primitives ....................................................................45
Section 10.7: The double primitive ...........................................................................................................................46
Section 10.8: The long primitive ...............................................................................................................................47
Section 10.9: The boolean primitive .........................................................................................................................48
Section 10.10: The byte primitive .............................................................................................................................48
Section 10.11: Negative value representation ..........................................................................................................49
Section 10.12: The short primitive ............................................................................................................................50
Chapter 11: Strings .......................................................................................................................51
Section 11.1: Comparing Strings ..............................................................................................................................51
Section 11.2: Changing the case of characters within a String ................................................................................53
Section 11.3: Finding a String Within Another String ...............................................................................................55
Section 11.4: String pool and heap storage .............................................................................................................56
Section 11.5: Splitting Strings ...................................................................................................................................57
Section 11.6: Joining Strings with a delimiter ...........................................................................................................59
Section 11.7: String concatenation and StringBuilders ............................................................................................60
Section 11.8: Substrings ...........................................................................................................................................61
Section 11.9: Platform independent new line separator ...........................................................................................62
Section 11.10: Reversing Strings .............................................................................................................................62
Section 11.11: Adding toString() method for custom objects ...................................................................................63
Section 11.12: Remove Whitespace from the Beginning and End of a String .........................................................64
Section 11.13: Case insensitive switch ....................................................................................................................64
Section 11.14: Replacing parts of Strings ................................................................................................................65
Section 11.15: Getting the length of a String ............................................................................................................66
Section 11.16: Getting the nth character in a String .................................................................................................66
Section 11.17: Counting occurrences of a substring or character in a string ...........................................................66
Chapter 12: StringBu er ...............................................................................................................68
Section 12.1: String Bu er class ...............................................................................................................................68
Chapter 13: StringBuilder .............................................................................................................69
Section 13.1: Comparing StringBu er, StringBuilder, Formatter and StringJoiner ..................................................69
Section 13.2: Repeat a String n times ......................................................................................................................70
Chapter 14: String Tokenizer........................................................................................................71
Section 14.1: StringTokenizer Split by space ...........................................................................................................71
Section 14.2: StringTokenizer Split by comma ',' .....................................................................................................71
Chapter 15: Splitting a string into fixed length parts .................................................................72
Section 15.1: Break a string up into substrings all of a known length ......................................................................72
Section 15.2: Break a string up into substrings all of variable length .......................................................................72
Chapter 16: Date Class .................................................................................................................73
Section 16.1: Convert java.util.Date to java.sql.Date ...............................................................................................73
Section 16.2: A basic date output .............................................................................................................................73
Section 16.3: Java 8 LocalDate and LocalDateTime objects ...................................................................................74
Section 16.4: Creating a Specific Date .....................................................................................................................75
Section 16.5: Converting Date to a certain String format .........................................................................................75
Section 16.6: LocalTime ...........................................................................................................................................76
Section 16.7: Convert formatted string representation of date to Date object..........................................................76
Section 16.8: Creating Date objects .........................................................................................................................77
Section 16.9: Comparing Date objects .....................................................................................................................77
Section 16.10: Converting String into Date ..............................................................................................................80
Section 16.11: Time Zones and java.util.Date ..........................................................................................................80
Chapter 17: Dates and Time (java.time.*) ....................................................................................82
Section 17.1: Calculate Di erence between 2 LocalDates ......................................................................................82
Section 17.2: Date and time .....................................................................................................................................82
Section 17.3: Operations on dates and times ...........................................................................................................82
Section 17.4: Instant .................................................................................................................................................82
Section 17.5: Usage of various classes of Date Time API .......................................................................................83
Section 17.6: Date Time Formatting .........................................................................................................................85
Section 17.7: Simple Date Manipulations .................................................................................................................85
Chapter 18: LocalTime ..................................................................................................................87
Section 18.1: Amount of time between two LocalTime.............................................................................................87
Section 18.2: Intro .....................................................................................................................................................88
Section 18.3: Time Modification ................................................................................................................................88
Section 18.4: Time Zones and their time di erence .................................................................................................88
Chapter 19: BigDecimal ................................................................................................................90
Section 19.1: Comparing BigDecimals .....................................................................................................................90
Section 19.2: Using BigDecimal instead of float .......................................................................................................90
Section 19.3: BigDecimal.valueOf() ..........................................................................................................................91
Section 19.4: Mathematical operations with BigDecimal ..........................................................................................91
Section 19.5: Initialization of BigDecimals with value zero, one or ten ....................................................................94
Section 19.6: BigDecimal objects are immutable .....................................................................................................94
Chapter 20: BigInteger ..................................................................................................................96
Section 20.1: Initialization .........................................................................................................................................96
Section 20.2: BigInteger Mathematical Operations Examples .................................................................................97
Section 20.3: Comparing BigIntegers .......................................................................................................................99
Section 20.4: Binary Logic Operations on BigInteger ............................................................................................ 100
Section 20.5: Generating random BigIntegers ...................................................................................................... 101
Chapter 21: NumberFormat ........................................................................................................ 103
Section 21.1: NumberFormat ................................................................................................................................. 103
Chapter 22: Bit Manipulation ...................................................................................................... 104
Section 22.1: Checking, setting, clearing, and toggling individual bits. Using long as bit mask ........................... 104
Section 22.2: java.util.BitSet class ......................................................................................................................... 104
Section 22.3: Checking if a number is a power of 2 .............................................................................................. 105
Section 22.4: Signed vs unsigned shift .................................................................................................................. 107
Section 22.5: Expressing the power of 2 ............................................................................................................... 107
Section 22.6: Packing / unpacking values as bit fragments .................................................................................. 108
Chapter 23: Arrays ...................................................................................................................... 109
Section 23.1: Creating and Initializing Arrays ........................................................................................................ 109
Section 23.2: Creating a List from an Array ........................................................................................................... 115
Section 23.3: Creating an Array from a Collection ................................................................................................ 117
Section 23.4: Multidimensional and Jagged Arrays ............................................................................................... 117
Section 23.5: ArrayIndexOutOfBoundsException .................................................................................................. 119
Section 23.6: Array Covariance ............................................................................................................................. 120
Section 23.7: Arrays to Stream .............................................................................................................................. 121
Section 23.8: Iterating over arrays ......................................................................................................................... 121
Section 23.9: Arrays to a String ............................................................................................................................. 123
Section 23.10: Sorting arrays ................................................................................................................................ 124
Section 23.11: Getting the Length of an Array ...................................................................................................... 126
Section 23.12: Finding an element in an array ...................................................................................................... 126
Section 23.13: How do you change the size of an array? ..................................................................................... 127
Section 23.14: Converting arrays between primitives and boxed types ................................................................ 128
Section 23.15: Remove an element from an array ................................................................................................ 129
Section 23.16: Comparing arrays for equality ....................................................................................................... 130
Section 23.17: Copying arrays ............................................................................................................................... 130
Section 23.18: Casting Arrays ............................................................................................................................... 131
Chapter 24: Collections .............................................................................................................. 133
Section 24.1: Removing items from a List within a loop ........................................................................................ 133
Section 24.2: Constructing collections from existing data ..................................................................................... 135
Section 24.3: Declaring an ArrayList and adding objects ...................................................................................... 137
Section 24.4: Iterating over Collections ................................................................................................................. 137
Section 24.5: Immutable Empty Collections .......................................................................................................... 139
Section 24.6: Sub Collections ................................................................................................................................ 139
Section 24.7: Unmodifiable Collection ................................................................................................................... 140
Section 24.8: Pitfall: concurrent modification exceptions ...................................................................................... 141
Section 24.9: Removing matching items from Lists using Iterator ........................................................................ 141
Section 24.10: Join lists ......................................................................................................................................... 142
Section 24.11: Creating your own Iterable structure for use with Iterator or for-each loop ................................... 142
Section 24.12: Collections and Primitive Values ................................................................................................... 144
Chapter 25: Lists ......................................................................................................................... 146
Section 25.1: Sorting a generic list ........................................................................................................................ 146
Section 25.2: Convert a list of integers to a list of strings ...................................................................................... 147
Section 25.3: Classes implementing List - Pros and Cons .................................................................................... 147
Section 25.4: Finding common elements between 2 lists...................................................................................... 150
Section 25.5: In-place replacement of a List element............................................................................................ 150
Section 25.6: Making a list unmodifiable ............................................................................................................... 151
Section 25.7: Moving objects around in the list ..................................................................................................... 151
Section 25.8: Creating, Adding and Removing element from an ArrayList ........................................................... 152
Section 25.9: Creating a List .................................................................................................................................. 152
Section 25.10: Positional Access Operations ........................................................................................................ 153
Section 25.11: Iterating over elements in a list ...................................................................................................... 155
Section 25.12: Removing elements from list B that are present in the list A ......................................................... 155
Chapter 26: Sets .......................................................................................................................... 157
Section 26.1: Initialization ...................................................................................................................................... 157
Section 26.2: Basics of Set .................................................................................................................................... 157
Section 26.3: Types and Usage of Sets ................................................................................................................ 158
Section 26.4: Create a list from an existing Set ..................................................................................................... 159
Section 26.5: Eliminating duplicates using Set ...................................................................................................... 159
Section 26.6: Declaring a HashSet with values ..................................................................................................... 160
Chapter 27: List vs Set ................................................................................................................ 161
Section 27.1: List vs Set ........................................................................................................................................ 161
Chapter 28: Maps ........................................................................................................................ 162
Section 28.1: Iterating Map Entries E ciently ....................................................................................................... 162
Section 28.2: Usage of HashMap .......................................................................................................................... 164
Section 28.3: Using Default Methods of Map from Java 8 .................................................................................... 165
Section 28.4: Iterating through the contents of a Map ........................................................................................... 167
Section 28.5: Merging, combine and composing Maps ......................................................................................... 168
Section 28.6: Add multiple items ........................................................................................................................... 169
Section 28.7: Creating and Initializing Maps ......................................................................................................... 171
Section 28.8: Check if key exists ........................................................................................................................... 172
Section 28.9: Add an element ................................................................................................................................ 172
Section 28.10: Clear the map ................................................................................................................................ 173
Section 28.11: Use custom object as key .............................................................................................................. 173
Chapter 29: LinkedHashMap ...................................................................................................... 175
Section 29.1: Java LinkedHashMap class ............................................................................................................. 175
Chapter 30: WeakHashMap ........................................................................................................ 176
Section 30.1: Concepts of WeakHashmap ............................................................................................................ 176
Chapter 31: SortedMap ............................................................................................................... 177
Section 31.1: Introduction to sorted Map ............................................................................................................... 177
Chapter 32: TreeMap and TreeSet ............................................................................................. 178
Section 32.1: TreeMap of a simple Java type ....................................................................................................... 178
Section 32.2: TreeSet of a simple Java Type ........................................................................................................ 178
Section 32.3: TreeMap/TreeSet of a custom Java type ........................................................................................ 179
Section 32.4: TreeMap and TreeSet Thread Safety .............................................................................................. 180
Chapter 33: Queues and Deques ............................................................................................... 182
Section 33.1: The usage of the PriorityQueue ....................................................................................................... 182
Section 33.2: Deque .............................................................................................................................................. 182
Section 33.3: Stacks .............................................................................................................................................. 183
Section 33.4: BlockingQueue ................................................................................................................................ 184
Section 33.5: LinkedList as a FIFO Queue ............................................................................................................ 185
Section 33.6: Queue Interface ............................................................................................................................... 186
Chapter 34: Dequeue Interface................................................................................................... 187
Section 34.1: Adding Elements to Deque .............................................................................................................. 187
Section 34.2: Removing Elements from Deque ..................................................................................................... 187
Section 34.3: Retrieving Element without Removing ............................................................................................. 187
Section 34.4: Iterating through Deque ................................................................................................................... 187
Chapter 35: Enums ...................................................................................................................... 189
Section 35.1: Declaring and using a basic enum .................................................................................................. 189
Section 35.2: Enums with constructors.................................................................................................................. 192
Section 35.3: Enums with Abstract Methods ......................................................................................................... 193
Section 35.4: Implements Interface ....................................................................................................................... 194
Section 35.5: Implement Singleton pattern with a single-element enum............................................................... 195
Section 35.6: Using methods and static blocks ..................................................................................................... 196
Section 35.7: Zero instance enum ......................................................................................................................... 196
Section 35.8: Enum as a bounded type parameter ............................................................................................... 197
Section 35.9: Documenting enums ........................................................................................................................ 197
Section 35.10: Enum constant specific body ......................................................................................................... 198
Section 35.11: Getting the values of an enum ....................................................................................................... 199
Section 35.12: Enum Polymorphism Pattern ......................................................................................................... 200
Section 35.13: Compare and Contains for Enum values ...................................................................................... 201
Section 35.14: Get enum constant by name ......................................................................................................... 201
Section 35.15: Enum with properties (fields) ......................................................................................................... 202
Section 35.16: Convert enum to String .................................................................................................................. 203
Section 35.17: Enums with static fields ................................................................................................................. 203
Chapter 36: Enum Map................................................................................................................ 205
Section 36.1: Enum Map Book Example ............................................................................................................... 205
Chapter 37: EnumSet class ........................................................................................................ 206
Section 37.1: Enum Set Example .......................................................................................................................... 206
Chapter 38: Enum starting with number ................................................................................... 207
Section 38.1: Enum with name at beginning ......................................................................................................... 207
Chapter 39: Hashtable ................................................................................................................ 208
Section 39.1: Hashtable ......................................................................................................................................... 208
Chapter 40: Operators ................................................................................................................ 209
Section 40.1: The Increment/Decrement Operators (++/--) ................................................................................... 209
Section 40.2: The Conditional Operator (? :) ......................................................................................................... 209
Section 40.3: The Bitwise and Logical Operators (~, &, |, ^) ................................................................................. 211
Section 40.4: The String Concatenation Operator (+) ........................................................................................... 212
Section 40.5: The Arithmetic Operators (+, -, *, /, %) ............................................................................................ 214
Section 40.6: The Shift Operators (<<, >> and >>>) ............................................................................................. 216
Section 40.7: The Instanceof Operator .................................................................................................................. 217
Section 40.8: The Assignment Operators (=, +=, -=, *=, /=, %=, <<=, >>= , >>>=, &=, |= and ^=) ....................... 218
Section 40.9: The conditional-and and conditional-or Operators ( && and || ) ...................................................... 220
Section 40.10: The Relational Operators (<, <=, >, >=) ........................................................................................ 221
Section 40.11: The Equality Operators (==, !=) ..................................................................................................... 222
Section 40.12: The Lambda operator ( -> ) ........................................................................................................... 224
Chapter 41: Constructors ........................................................................................................... 225
Section 41.1: Default Constructor .......................................................................................................................... 225
Section 41.2: Call parent constructor..................................................................................................................... 226
Section 41.3: Constructor with Arguments ............................................................................................................ 227
Chapter 42: Object Class Methods and Constructor ............................................................... 229
Section 42.1: hashCode() method ......................................................................................................................... 229
Section 42.2: toString() method ............................................................................................................................. 231
Section 42.3: equals() method ............................................................................................................................... 232
Section 42.4: wait() and notify() methods .............................................................................................................. 234
Section 42.5: getClass() method ........................................................................................................................... 236
Section 42.6: clone() method ................................................................................................................................. 237
Section 42.7: Object constructor ............................................................................................................................ 238
Section 42.8: finalize() method .............................................................................................................................. 239
Chapter 43: Annotations ............................................................................................................. 241
Section 43.1: The idea behind Annotations ........................................................................................................... 241
Section 43.2: Defining annotation types ................................................................................................................ 241
Section 43.3: Runtime annotation checks via reflection ........................................................................................ 243
Section 43.4: Built-in annotations .......................................................................................................................... 243
Section 43.5: Compile time processing using annotation processor ..................................................................... 246
Section 43.6: Repeating Annotations .................................................................................................................... 250
Section 43.7: Inherited Annotations ....................................................................................................................... 251
Section 43.8: Getting Annotation values at run-time ............................................................................................. 252
Section 43.9: Annotations for 'this' and receiver parameters ................................................................................ 253
Section 43.10: Add multiple annotation values ...................................................................................................... 254
Chapter 44: Immutable Class ..................................................................................................... 255
Section 44.1: Example without mutable refs ......................................................................................................... 255
Section 44.2: What is the advantage of immutability? ........................................................................................... 255
Section 44.3: Rules to define immutable classes .................................................................................................. 255
Section 44.4: Example with mutable refs .............................................................................................................. 256
Chapter 45: Immutable Objects .................................................................................................. 257
Section 45.1: Creating an immutable version of a type using defensive copying ................................................. 257
Section 45.2: The recipe for an immutable class ................................................................................................... 257
Section 45.3: Typical design flaws which prevent a class from being immutable ................................................. 258
Chapter 46: Visibility (controlling access to members of a class) .......................................... 262
Section 46.1: Private Visibility ................................................................................................................................ 262
Section 46.2: Public Visibility ................................................................................................................................. 262
Section 46.3: Package Visibility ............................................................................................................................. 263
Section 46.4: Protected Visibility ........................................................................................................................... 263
Section 46.5: Summary of Class Member Access Modifiers ................................................................................. 264
Section 46.6: Interface members ........................................................................................................................... 264
Chapter 47: Generics .................................................................................................................. 265
Section 47.1: Creating a Generic Class ................................................................................................................ 265
Section 47.2: Deciding between `T`, `? super T`, and `? extends T` .................................................................... 267
Section 47.3: The Diamond ................................................................................................................................... 269
Section 47.4: Declaring a Generic Method ............................................................................................................ 269
Section 47.5: Requiring multiple upper bounds ("extends A & B") ........................................................................ 270
Section 47.6: Obtain class that satisfies generic parameter at runtime ................................................................ 270
Section 47.7: Benefits of Generic class and interface ........................................................................................... 271
Section 47.8: Instantiating a generic type .............................................................................................................. 272
Section 47.9: Creating a Bounded Generic Class ................................................................................................. 272
Section 47.10: Referring to the declared generic type within its own declaration ................................................. 274
Section 47.11: Binding generic parameter to more than 1 type ............................................................................ 275
Section 47.12: Using Generics to auto-cast .......................................................................................................... 276
Section 47.13: Use of instanceof with Generics .................................................................................................... 276
Section 47.14: Di erent ways for implementing a Generic Interface (or extending a Generic Class) .................. 278
Chapter 48: Classes and Objects ............................................................................................... 280
Section 48.1: Overloading Methods....................................................................................................................... 280
Section 48.2: Explaining what is method overloading and overriding ................................................................... 281
Section 48.3: Constructors .................................................................................................................................... 283
Section 48.4: Initializing static final fields using a static initializer ......................................................................... 284
Section 48.5: Basic Object Construction and Use ................................................................................................. 285
Section 48.6: Simplest Possible Class .................................................................................................................. 287
Section 48.7: Object Member vs Static Member ................................................................................................... 287
Chapter 49: Local Inner Class .................................................................................................... 289
Section 49.1: Local Inner Class ............................................................................................................................. 289
Chapter 50: Nested and Inner Classes ...................................................................................... 290
Section 50.1: A Simple Stack Using a Nested Class ............................................................................................. 290
Section 50.2: Static vs Non Static Nested Classes ............................................................................................... 290
Section 50.3: Access Modifiers for Inner Classes ................................................................................................. 292
Section 50.4: Anonymous Inner Classes ............................................................................................................... 293
Section 50.5: Create instance of non-static inner class from outside .................................................................... 294
Section 50.6: Method Local Inner Classes ............................................................................................................ 295
Section 50.7: Accessing the outer class from a non-static inner class.................................................................. 295
Chapter 51: The java.util.Objects Class .................................................................................... 297
Section 51.1: Basic use for object null check ........................................................................................................ 297
Section 51.2: Objects.nonNull() method reference use in stream api ................................................................... 297
Chapter 52: Default Methods ...................................................................................................... 298
Section 52.1: Basic usage of default methods ...................................................................................................... 298
Section 52.2: Accessing overridden default methods from implementing class ................................................... 298
Section 52.3: Why use Default Methods? ............................................................................................................. 299
Section 52.4: Accessing other interface methods within default method .............................................................. 299
Section 52.5: Default method multiple inheritance collision .................................................................................. 300
Section 52.6: Class, Abstract class and Interface method precedence ................................................................ 301
Chapter 53: Packages ................................................................................................................. 303
Section 53.1: Using Packages to create classes with the same name ................................................................. 303
Section 53.2: Using Package Protected Scope ..................................................................................................... 303
Chapter 54: Inheritance............................................................................................................... 305
Section 54.1: Inheritance ....................................................................................................................................... 305
Section 54.2: Abstract Classes .............................................................................................................................. 306
Section 54.3: Using 'final' to restrict inheritance and overriding ............................................................................ 308
Section 54.4: The Liskov Substitution Principle ..................................................................................................... 309
Section 54.5: Abstract class and Interface usage: "Is-a" relation vs "Has-a" capability ........................................ 310
Section 54.6: Static Inheritance ............................................................................................................................. 313
Section 54.7: Programming to an interface ........................................................................................................... 314
Section 54.8: Overriding in Inheritance.................................................................................................................. 316
Section 54.9: Variable shadowing ......................................................................................................................... 317
Section 54.10: Narrowing and Widening of object references .............................................................................. 317
Section 54.11: Inheritance and Static Methods ..................................................................................................... 318
Chapter 55: Reference Types ..................................................................................................... 320
Section 55.1: Di erent Reference Types ............................................................................................................... 320
Chapter 56: Console I/O .............................................................................................................. 322
Section 56.1: Reading user input from the console ............................................................................................... 322
Section 56.2: Aligning strings in console ............................................................................................................... 323
Section 56.3: Implementing Basic Command-Line Behavior ................................................................................ 324
Chapter 57: Streams ................................................................................................................... 326
Section 57.1: Using Streams ................................................................................................................................. 326
Section 57.2: Consuming Streams ........................................................................................................................ 328
Section 57.3: Creating a Frequency Map .............................................................................................................. 330
Section 57.4: Infinite Streams ................................................................................................................................ 330
Section 57.5: Collect Elements of a Stream into a Collection ............................................................................... 331
Section 57.6: Using Streams to Implement Mathematical Functions .................................................................... 334
Section 57.7: Flatten Streams with flatMap() ......................................................................................................... 334
Section 57.8: Parallel Stream ................................................................................................................................ 335
Section 57.9: Creating a Stream ............................................................................................................................ 336
Section 57.10: Finding Statistics about Numerical Streams .................................................................................. 337
Section 57.11: Converting an iterator to a stream ................................................................................................. 337
Section 57.12: Using IntStream to iterate over indexes ........................................................................................ 337
Section 57.13: Concatenate Streams .................................................................................................................... 338
Section 57.14: Reduction with Streams ................................................................................................................. 338
Section 57.15: Using Streams of Map.Entry to Preserve Initial Values after Mapping ......................................... 341
Section 57.16: IntStream to String ......................................................................................................................... 341
Section 57.17: Finding the First Element that Matches a Predicate ...................................................................... 341
Section 57.18: Using Streams and Method References to Write Self-Documenting Processes .......................... 342
Section 57.19: Converting a Stream of Optional to a Stream of Values ............................................................... 343
Section 57.20: Get a Slice of a Stream ................................................................................................................. 343
Section 57.21: Create a Map based on a Stream ................................................................................................. 343
Section 57.22: Joining a stream to a single String ................................................................................................ 344
Section 57.23: Sort Using Stream ......................................................................................................................... 345
Section 57.24: Streams of Primitives ..................................................................................................................... 346
Section 57.25: Stream operations categories ........................................................................................................ 346
Section 57.26: Collect Results of a Stream into an Array...................................................................................... 347
Section 57.27: Generating random Strings using Streams ................................................................................... 347
Chapter 58: InputStreams and OutputStreams ......................................................................... 349
Section 58.1: Closing Streams .............................................................................................................................. 349
Section 58.2: Reading InputStream into a String .................................................................................................. 349
Section 58.3: Wrapping Input/Output Streams ...................................................................................................... 350
Section 58.4: DataInputStream Example .............................................................................................................. 351
Section 58.5: Writing bytes to an OutputStream ................................................................................................... 351
Section 58.6: Copying Input Stream to Output Stream ......................................................................................... 351
Chapter 59: Readers and Writers ............................................................................................... 353
Section 59.1: Bu eredReader ............................................................................................................................... 353
Section 59.2: StringWriter Example ....................................................................................................................... 354
Chapter 60: Preferences ............................................................................................................. 355
Section 60.1: Using preferences ............................................................................................................................ 355
Section 60.2: Adding event listeners ..................................................................................................................... 355
Section 60.3: Getting sub-nodes of Preferences ................................................................................................... 356
Section 60.4: Coordinating preferences access across multiple application instances ........................................ 357
Section 60.5: Exporting preferences...................................................................................................................... 357
Section 60.6: Importing preferences ...................................................................................................................... 358
Section 60.7: Removing event listeners ................................................................................................................ 359
Section 60.8: Getting preferences values .............................................................................................................. 360
Section 60.9: Setting preferences values .............................................................................................................. 360
Chapter 61: Collection Factory Methods ................................................................................... 361
Section 61.1: List<E> Factory Method Examples .................................................................................................. 361
Section 61.2: Set<E> Factory Method Examples .................................................................................................. 361
Section 61.3: Map<K, V> Factory Method Examples ............................................................................................ 361
Chapter 62: Alternative Collections ........................................................................................... 362
Section 62.1: Multimap in Guava, Apache and Eclipse Collections ...................................................................... 362
Section 62.2: Apache HashBag, Guava HashMultiset and Eclipse HashBag ...................................................... 364
Section 62.3: Compare operation with collections - Create collections ................................................................. 366
Chapter 63: Concurrent Collections .......................................................................................... 371
Section 63.1: Thread-safe Collections ................................................................................................................... 371
Section 63.2: Insertion into ConcurrentHashMap .................................................................................................. 371
Section 63.3: Concurrent Collections .................................................................................................................... 372
Chapter 64: Choosing Collections ............................................................................................. 374
Section 64.1: Java Collections Flowchart .............................................................................................................. 374
Chapter 65: super keyword ........................................................................................................ 375
Section 65.1: Super keyword use with examples .................................................................................................. 375
Chapter 66: Serialization............................................................................................................. 378
Section 66.1: Basic Serialization in Java ............................................................................................................... 378
Section 66.2: Custom Serialization ........................................................................................................................ 379
Section 66.3: Versioning and serialVersionUID ..................................................................................................... 382
Section 66.4: Serialization with Gson .................................................................................................................... 383
Section 66.5: Custom JSON Deserialization with Jackson ................................................................................... 384
Chapter 67: Optional ................................................................................................................... 387
Section 67.1: Map .................................................................................................................................................. 387
Section 67.2: Return default value if Optional is empty ......................................................................................... 388
Section 67.3: Throw an exception, if there is no value .......................................................................................... 388
Section 67.4: Lazily provide a default value using a Supplier ............................................................................... 388
Section 67.5: Filter ................................................................................................................................................. 389
Section 67.6: Using Optional containers for primitive number types ..................................................................... 389
Section 67.7: Run code only if there is a value present ........................................................................................ 390
Section 67.8: FlatMap ............................................................................................................................................ 390
Chapter 68: Object References .................................................................................................. 391
Section 68.1: Object References as method parameters ...................................................................................... 391
Chapter 69: Exceptions and exception handling ...................................................................... 394
Section 69.1: Catching an exception with try-catch ............................................................................................... 394
Section 69.2: The try-with-resources statement .................................................................................................... 395
Section 69.3: Custom Exceptions .......................................................................................................................... 398
Section 69.4: Handling InterruptedException ........................................................................................................ 400
Section 69.5: Return statements in try catch block ............................................................................................... 401
Section 69.6: Introduction ...................................................................................................................................... 402
Section 69.7: The Java Exception Hierarchy - Unchecked and Checked Exceptions .......................................... 403
Section 69.8: Creating and reading stacktraces .................................................................................................... 406
Section 69.9: Throwing an exception..................................................................................................................... 409
Section 69.10: Advanced features of Exceptions .................................................................................................. 411
Section 69.11: The try-finally and try-catch-finally statements .............................................................................. 412
Section 69.12: The 'throws' clause in a method declaration.................................................................................. 414
Chapter 70: Calendar and its Subclasses ................................................................................. 416
Section 70.1: Creating Calendar objects ............................................................................................................... 416
Section 70.2: Increasing / Decreasing calendar fields........................................................................................... 416
Section 70.3: Subtracting calendars ...................................................................................................................... 416
Section 70.4: Finding AM/PM ................................................................................................................................ 416
Chapter 71: Using the static keyword ....................................................................................... 418
Section 71.1: Reference to non-static member from static context ....................................................................... 418
Section 71.2: Using static to declare constants ..................................................................................................... 418
Chapter 72: Properties Class ..................................................................................................... 420
Section 72.1: Loading properties ........................................................................................................................... 420
Section 72.2: Saving Properties as XML ............................................................................................................... 420
Section 72.3: Property files caveat: trailing whitespace ........................................................................................ 421
Chapter 73: Lambda Expressions .............................................................................................. 424
Section 73.1: Introduction to Java lambdas ........................................................................................................... 424
Section 73.2: Using Lambda Expressions to Sort a Collection ............................................................................. 427
Section 73.3: Method References ......................................................................................................................... 428
Section 73.4: Implementing multiple interfaces ..................................................................................................... 430
Section 73.5: Lambda - Listener Example ............................................................................................................. 430
Section 73.6: Java Closures with lambda expressions ......................................................................................... 431
Section 73.7: Lambdas and memory utilization ..................................................................................................... 432
Section 73.8: Using lambda expression with your own functional interface .......................................................... 433
Section 73.9: Traditional style to Lambda style ..................................................................................................... 433
Section 73.10: `return` only returns from the lambda, not the outer method ........................................................ 434
Section 73.11: Lambdas and Execute-around Pattern .......................................................................................... 436
Section 73.12: Using lambda expressions & predicates to get a certain value(s) from a list ................................ 436
Chapter 74: Basic Control Structures ....................................................................................... 438
Section 74.1: Switch statement ............................................................................................................................. 438
Section 74.2: do while Loop .................................................................................................................................. 439
Section 74.3: For Each .......................................................................................................................................... 440
Section 74.4: Continue Statement in Java ............................................................................................................ 441
Section 74.5: If / Else If / Else Control ................................................................................................................... 441
Section 74.6: For Loops ......................................................................................................................................... 441
Section 74.7: Ternary Operator ............................................................................................................................. 442
Section 74.8: Try ... Catch ... Finally ........................................................................................................................ 443
Section 74.9: Break................................................................................................................................................ 443
Section 74.10: While Loops ................................................................................................................................... 444
Section 74.11: If / Else ........................................................................................................................................... 444
Section 74.12: Nested break / continue ................................................................................................................. 444
Chapter 75: Bu eredWriter ........................................................................................................ 446
Section 75.1: Write a line of text to File ................................................................................................................. 446
Chapter 76: New File I/O ............................................................................................................. 447
Section 76.1: Creating paths ................................................................................................................................. 447
Section 76.2: Manipulating paths ........................................................................................................................... 447
Section 76.3: Retrieving information about a path ................................................................................................. 447
Section 76.4: Retrieving information using the filesystem ..................................................................................... 448
Section 76.5: Reading files .................................................................................................................................... 449
Section 76.6: Writing files ...................................................................................................................................... 449
Chapter 77: File I/O ...................................................................................................................... 450
Section 77.1: Migrating from java.io.File to Java 7 NIO (java.nio.file.Path) .......................................................... 450
Section 77.2: Reading an image from a file ........................................................................................................... 452
Section 77.3: File Read/Write Using FileInputStream/FileOutputStream .............................................................. 452
Section 77.4: Reading all bytes to a byte[] ............................................................................................................ 453
Section 77.5: Copying a file using Channel ........................................................................................................... 454
Section 77.6: Writing a byte[] to a file .................................................................................................................... 454
Section 77.7: Stream vs Writer/Reader API .......................................................................................................... 455
Section 77.8: Reading a file with a Scanner .......................................................................................................... 456
Section 77.9: Copying a file using InputStream and OutputStream ...................................................................... 457
Section 77.10: Reading from a binary file .............................................................................................................. 457
Section 77.11: Reading a file using Channel and Bu er ....................................................................................... 457
Section 77.12: Adding Directories ......................................................................................................................... 458
Section 77.13: Blocking or redirecting standard output / error .............................................................................. 459
Section 77.14: Reading a whole file at once ......................................................................................................... 460
Section 77.15: Locking .......................................................................................................................................... 460
Section 77.16: Reading a file using Bu eredInputStream ..................................................................................... 460
Section 77.17: Iterate over a directory printing subdirectories in it ........................................................................ 461
Section 77.18: Writing a file using Channel and Bu er ......................................................................................... 461
Section 77.19: Writing a file using PrintStream ..................................................................................................... 462
Section 77.20: Iterating over a directory and filter by file extension ...................................................................... 462
Section 77.21: Accessing the contents of a ZIP file .............................................................................................. 463
Chapter 78: Scanner ................................................................................................................... 464
Section 78.1: General Pattern that does most commonly asked about tasks ....................................................... 464
Section 78.2: Using custom delimiters................................................................................................................... 466
Section 78.3: Reading system input using Scanner .............................................................................................. 466
Section 78.4: Reading file input using Scanner ..................................................................................................... 466
Section 78.5: Read the entire input as a String using Scanner ............................................................................. 467
Section 78.6: Carefully Closing a Scanner ............................................................................................................ 467
Section 78.7: Read an int from the command line ................................................................................................. 468
Chapter 79: Interfaces ................................................................................................................. 469
Section 79.1: Implementing multiple interfaces ..................................................................................................... 469
Section 79.2: Declaring and Implementing an Interface ........................................................................................ 470
Section 79.3: Extending an interface ..................................................................................................................... 470
Section 79.4: Usefulness of interfaces .................................................................................................................. 471
Section 79.5: Default methods ............................................................................................................................... 473
Section 79.6: Modifiers in Interfaces...................................................................................................................... 475
Section 79.7: Using Interfaces with Generics ........................................................................................................ 475
Section 79.8: Strengthen bounded type parameters ............................................................................................. 478
Section 79.9: Implementing interfaces in an abstract class .................................................................................. 478
Chapter 80: Regular Expressions .............................................................................................. 480
Section 80.1: Using capture groups ....................................................................................................................... 480
Section 80.2: Using regex with custom behaviour by compiling the Pattern with flags ......................................... 481
Section 80.3: Escape Characters .......................................................................................................................... 481
Section 80.4: Not matching a given string ............................................................................................................. 482
Section 80.5: Matching with a regex literal ............................................................................................................ 482
Section 80.6: Matching a backslash ...................................................................................................................... 482
Chapter 81: Comparable and Comparator ................................................................................ 484
Section 81.1: Sorting a List using Comparable<T> or a Comparator<T> ............................................................. 484
Section 81.2: The compareTo and compare Methods .......................................................................................... 487
Section 81.3: Natural (comparable) vs explicit (comparator) sorting ..................................................................... 488
Section 81.4: Creating a Comparator using comparing method ........................................................................... 489
Section 81.5: Sorting Map entries .......................................................................................................................... 489
Chapter 82: Java Floating Point Operations ............................................................................. 491
Section 82.1: Comparing floating point values ...................................................................................................... 491
Section 82.2: OverFlow and UnderFlow ................................................................................................................ 493
Section 82.3: Formatting the floating point values ................................................................................................. 494
Section 82.4: Strict Adherence to the IEEE Specification ..................................................................................... 494
Chapter 83: Currency and Money .............................................................................................. 496
Section 83.1: Add custom currency ....................................................................................................................... 496
Chapter 84: Object Cloning ........................................................................................................ 497
Section 84.1: Cloning performing a deep copy ...................................................................................................... 497
Section 84.2: Cloning using a copy factory ........................................................................................................... 498
Section 84.3: Cloning using a copy constructor .................................................................................................... 498
Section 84.4: Cloning by implementing Clonable interface ................................................................................... 498
Section 84.5: Cloning performing a shallow copy .................................................................................................. 499
Chapter 85: Recursion ................................................................................................................ 501
Section 85.1: The basic idea of recursion ............................................................................................................. 501
Section 85.2: Deep recursion is problematic in Java ............................................................................................. 501
Section 85.3: Types of Recursion .......................................................................................................................... 503
Section 85.4: Computing the Nth Fibonacci Number ............................................................................................ 503
Section 85.5: StackOverflowError & recursion to loop .......................................................................................... 504
Section 85.6: Computing the Nth power of a number............................................................................................ 506
Section 85.7: Traversing a Tree data structure with recursion .............................................................................. 506
Section 85.8: Reverse a string using Recursion .................................................................................................... 507
Section 85.9: Computing the sum of integers from 1 to N ..................................................................................... 507
Chapter 86: Converting to and from Strings ............................................................................. 508
Section 86.1: Converting String to other datatypes ............................................................................................... 508
Section 86.2: Conversion to / from bytes ............................................................................................................... 509
Section 86.3: Base64 Encoding / Decoding .......................................................................................................... 509
Section 86.4: Converting other datatypes to String ............................................................................................... 510
Section 86.5: Getting a `String` from an `InputStream` ......................................................................................... 511
Chapter 87: Random Number Generation ................................................................................. 512
Section 87.1: Pseudo Random Numbers .............................................................................................................. 512
Section 87.2: Pseudo Random Numbers in Specific Range ................................................................................. 512
Section 87.3: Generating cryptographically secure pseudorandom numbers ....................................................... 513
Section 87.4: Generating Random Numbers with a Specified Seed ..................................................................... 513
Section 87.5: Select random numbers without duplicates ..................................................................................... 514
Section 87.6: Generating Random number using apache-common lang3............................................................ 515
Chapter 88: Singletons ............................................................................................................... 516
Section 88.1: Enum Singleton ............................................................................................................................... 516
Section 88.2: Singleton without use of Enum (eager initialization) ........................................................................ 516
Section 88.3: Thread-safe lazy initialization using holder class | Bill Pugh Singleton implementation ................. 517
Section 88.4: Thread safe Singleton with double checked locking ....................................................................... 517
Section 88.5: Extending singleton (singleton inheritance) ..................................................................................... 518
Chapter 89: Autoboxing .............................................................................................................. 521
Section 89.1: Using int and Integer interchangeably ............................................................................................. 521
Section 89.2: Auto-unboxing may lead to NullPointerException ........................................................................... 522
Section 89.3: Using Boolean in if statement .......................................................................................................... 522
Section 89.4: Di erent Cases When Integer and int can be used interchangeably .............................................. 522
Section 89.5: Memory and Computational Overhead of Autoboxing .................................................................... 524
Chapter 90: 2D Graphics in Java ............................................................................................... 525
Section 90.1: Example 1: Draw and Fill a Rectangle Using Java ......................................................................... 525
Section 90.2: Example 2: Drawing and Filling Oval ............................................................................................... 527
Chapter 91: JAXB ........................................................................................................................ 528
Section 91.1: Reading an XML file (unmarshalling) .............................................................................................. 528
Section 91.2: Writing an XML file (marshalling an object) ..................................................................................... 528
Section 91.3: Manual field/property XML mapping configuration .......................................................................... 529
Section 91.4: Binding an XML namespace to a serializable Java class ................................................................ 530
Section 91.5: Using XmlAdapter to generate desired xml format .......................................................................... 530
Section 91.6: Using XmlAdapter to trim string ....................................................................................................... 532
Section 91.7: Automatic field/property XML mapping configuration (@XmlAccessorType).................................. 532
Section 91.8: Specifying a XmlAdapter instance to (re)use existing data ............................................................. 534
Chapter 92: Class - Java Reflection ........................................................................................... 537
Section 92.1: getClass() method of Object class ................................................................................................... 537
Chapter 93: Networking .............................................................................................................. 538
Section 93.1: Basic Client and Server Communication using a Socket ................................................................ 538
Section 93.2: Basic Client/Server Communication using UDP (Datagram) .......................................................... 540
Section 93.3: Loading TrustStore and KeyStore from InputStream ...................................................................... 541
Section 93.4: Socket example - reading a web page using a simple socket......................................................... 542
Section 93.5: Temporarily disable SSL verification (for testing purposes) ............................................................ 543
Section 93.6: Downloading a file using Channel ................................................................................................... 543
Section 93.7: Multicasting ...................................................................................................................................... 544
Chapter 94: NIO - Networking..................................................................................................... 547
Section 94.1: Using Selector to wait for events (example with OP_CONNECT) .................................................. 547
Chapter 95: HttpURLConnection ............................................................................................... 549
Section 95.1: Get response body from a URL as a String .................................................................................... 549
Section 95.2: POST data ....................................................................................................................................... 550
Section 95.3: Delete resource ............................................................................................................................... 550
Section 95.4: Check if resource exists................................................................................................................... 551
Chapter 96: JAX-WS .................................................................................................................... 553
Section 96.1: Basic Authentication ........................................................................................................................ 553
Chapter 97: Nashorn JavaScript engine.................................................................................... 554
Section 97.1: Execute JavaScript file .................................................................................................................... 554
Section 97.2: Intercept script output ...................................................................................................................... 554
Section 97.3: Hello Nashorn .................................................................................................................................. 555
Section 97.4: Evaluate Arithmetic Strings ............................................................................................................. 555
Section 97.5: Set global variables ......................................................................................................................... 555
Section 97.6: Set and get global variables ............................................................................................................ 556
Section 97.7: Usage of Java objects in JavaScript in Nashorn ............................................................................. 556
Section 97.8: Implementing an interface from script ............................................................................................. 557
Chapter 98: Java Native Interface .............................................................................................. 558
Section 98.1: Calling C++ methods from Java ...................................................................................................... 558
Section 98.2: Calling Java methods from C++ (callback) ...................................................................................... 559
Section 98.3: Loading native libraries .................................................................................................................... 561
Chapter 99: Functional Interfaces .............................................................................................. 563
Section 99.1: List of standard Java Runtime Library functional interfaces by signature ....................................... 563
Chapter 100: Fluent Interface ..................................................................................................... 565
Section 100.1: Fluent programming style .............................................................................................................. 565
Section 100.2: Truth - Fluent Testing Framework ................................................................................................. 566
Chapter 101: Remote Method Invocation (RMI) ........................................................................ 567
Section 101.1: Callback: invoking methods on a "client" ....................................................................................... 567
Section 101.2: Simple RMI example with Client and Server implementation ....................................................... 571
Section 101.3: Client-Server: invoking methods in one JVM from another ........................................................... 573
Chapter 102: Iterator and Iterable .............................................................................................. 576
Section 102.1: Removing elements using an iterator ............................................................................................ 576
Section 102.2: Creating your own Iterable ............................................................................................................ 576
Section 102.3: Using Iterable in for loop ................................................................................................................ 577
Section 102.4: Using the raw iterator..................................................................................................................... 578
Chapter 103: Reflection API ....................................................................................................... 579
Section 103.1: Dynamic Proxies ............................................................................................................................ 579
Section 103.2: Introduction .................................................................................................................................... 580
Section 103.3: Evil Java hacks with Reflection ..................................................................................................... 581
Section 103.4: Misuse of Reflection API to change private and final variables .................................................... 583
Section 103.5: Getting and Setting fields .............................................................................................................. 584
Section 103.6: Call constructor .............................................................................................................................. 585
Section 103.7: Call constructor of nested class ..................................................................................................... 586
Section 103.8: Invoking a method ......................................................................................................................... 586
Section 103.9: Get Class given its (fully qualified) name ...................................................................................... 587
Section 103.10: Getting the Constants of an Enumeration ................................................................................... 587
Section 103.11: Call overloaded constructors using reflection .............................................................................. 588
Chapter 104: ByteBu er ............................................................................................................. 590
Section 104.1: Basic Usage - Using DirectByteBu er ........................................................................................... 590
Section 104.2: Basic Usage - Creating a ByteBu er ............................................................................................. 590
Section 104.3: Basic Usage - Write Data to the Bu er .......................................................................................... 591
Chapter 105: Applets .................................................................................................................. 592
Section 105.1: Minimal Applet ............................................................................................................................... 592
Section 105.2: Creating a GUI ............................................................................................................................... 593
Section 105.3: Open links from within the applet .................................................................................................. 593
Section 105.4: Loading images, audio and other resources ................................................................................. 594
Chapter 106: Expressions .......................................................................................................... 596
Section 106.1: Operator Precedence .................................................................................................................... 596
Section 106.2: Expression Basics ......................................................................................................................... 597
Section 106.3: Expression evaluation order .......................................................................................................... 598
Section 106.4: Constant Expressions .................................................................................................................... 599
Chapter 107: JSON in Java ......................................................................................................... 601
Section 107.1: Using Jackson Object Mapper ....................................................................................................... 601
Section 107.2: JSON To Object (Gson Library) .................................................................................................... 602
Section 107.3: JSONObject.NULL ......................................................................................................................... 602
Section 107.4: JSON Builder - chaining methods ................................................................................................. 603
Section 107.5: Object To JSON (Gson Library) .................................................................................................... 603
Section 107.6: JSON Iteration ............................................................................................................................... 603
Section 107.7: optXXX vs getXXX methods .......................................................................................................... 604
Section 107.8: Extract single element from JSON ................................................................................................ 604
Section 107.9: JsonArray to Java List (Gson Library) ........................................................................................... 604
Section 107.10: Encoding data as JSON .............................................................................................................. 605
Section 107.11: Decoding JSON data ................................................................................................................... 605
Chapter 108: XML Parsing using the JAXP APIs ...................................................................... 607
Section 108.1: Parsing a document using the StAX API ....................................................................................... 607
Section 108.2: Parsing and navigating a document using the DOM API .............................................................. 608
Chapter 109: XML XPath Evaluation .......................................................................................... 610
Section 109.1: Parsing multiple XPath Expressions in a single XML .................................................................... 610
Section 109.2: Parsing single XPath Expression multiple times in an XML .......................................................... 610
Section 109.3: Evaluating a NodeList in an XML document ................................................................................. 611
Chapter 110: XOM - XML Object Model ..................................................................................... 612
Section 110.1: Reading a XML file ........................................................................................................................ 612
Section 110.2: Writing to a XML File ..................................................................................................................... 614
Chapter 111: Polymorphism ....................................................................................................... 617
Section 111.1: Method Overriding ......................................................................................................................... 617
Section 111.2: Method Overloading ...................................................................................................................... 618
Section 111.3: Polymorphism and di erent types of overriding ............................................................................ 619
Section 111.4: Virtual functions ............................................................................................................................. 622
Section 111.5: Adding behaviour by adding classes without touching existing code ............................................ 623
Chapter 112: Encapsulation ....................................................................................................... 625
Section 112.1: Encapsulation to maintain invariants ............................................................................................. 625
Section 112.2: Encapsulation to reduce coupling .................................................................................................. 626
Chapter 113: Java Agents........................................................................................................... 627
Section 113.1: Modifying classes with agents ....................................................................................................... 627
Section 113.2: Adding an agent at runtime ........................................................................................................... 627
Section 113.3: Setting up a basic agent ................................................................................................................ 628
Chapter 114: Varargs (Variable Argument) ............................................................................... 629
Section 114.1: Working with Varargs parameters ................................................................................................. 629
Section 114.2: Specifying a varargs parameter ..................................................................................................... 629
Chapter 115: Logging (java.util.logging) ................................................................................... 630
Section 115.1: Logging complex messages (e ciently) ......................................................................................... 630
Section 115.2: Using the default logger ................................................................................................................. 631
Section 115.3: Logging levels ................................................................................................................................ 632
Chapter 116: log4j / log4j2 .......................................................................................................... 634
Section 116.1: Properties-File to log to DB ........................................................................................................... 634
Section 116.2: How to get Log4j ............................................................................................................................ 634
Section 116.3: Setting up property file ................................................................................................................... 635
Section 116.4: Basic log4j2.xml configuration file ................................................................................................. 636
Section 116.5: How to use Log4j in Java code ...................................................................................................... 636
Section 116.6: Migrating from log4j 1.x to 2.x ....................................................................................................... 637
Section 116.7: Filter Logoutput by level (log4j 1.x) ................................................................................................ 638
Chapter 117: Oracle O cial Code Standard .............................................................................. 639
Section 117.1: Naming Conventions ..................................................................................................................... 639
Section 117.2: Class Structure .............................................................................................................................. 640
Section 117.3: Annotations .................................................................................................................................... 641
Section 117.4: Import statements .......................................................................................................................... 641
Section 117.5: Braces ............................................................................................................................................ 642
Section 117.6: Redundant Parentheses ................................................................................................................ 643
Section 117.7: Modifiers ........................................................................................................................................ 643
Section 117.8: Indentation ..................................................................................................................................... 644
Section 117.9: Literals ........................................................................................................................................... 644
Section 117.10: Package declaration .................................................................................................................... 644
Section 117.11: Lambda Expressions ................................................................................................................... 644
Section 117.12: Java Source Files ........................................................................................................................ 645
Section 117.13: Wrapping statements ................................................................................................................... 645
Section 117.14: Wrapping Method Declarations ................................................................................................... 646
Section 117.15: Wrapping Expressions ................................................................................................................. 646
Section 117.16: Whitespace .................................................................................................................................. 647
Section 117.17: Special Characters ...................................................................................................................... 647
Section 117.18: Variable Declarations................................................................................................................... 648
Chapter 118: Character encoding .............................................................................................. 649
Section 118.1: Reading text from a file encoded in UTF-8 .................................................................................... 649
Section 118.2: Writing text to a file in UTF-8 ......................................................................................................... 649
Section 118.3: Getting byte representation of a string in UTF-8 ........................................................................... 650
Chapter 119: Apache Commons Lang ....................................................................................... 651
Section 119.1: Implement equals() method ........................................................................................................... 651
Section 119.2: Implement hashCode() method ..................................................................................................... 651
Section 119.3: Implement toString() method ......................................................................................................... 652
Chapter 120: Localization and Internationalization .................................................................. 654
Section 120.1: Locale ............................................................................................................................................ 654
Section 120.2: Automatically formatted Dates using "locale" ................................................................................ 655
Section 120.3: String Comparison ......................................................................................................................... 655
Chapter 121: Parallel programming with Fork/Join framework............................................... 656
Section 121.1: Fork/Join Tasks in Java ................................................................................................................. 656
Chapter 122: Non-Access Modifiers .......................................................................................... 658
Section 122.1: final ................................................................................................................................................ 658
Section 122.2: static .............................................................................................................................................. 659
Section 122.3: abstract .......................................................................................................................................... 660
Section 122.4: strictfp ............................................................................................................................................ 661
Section 122.5: volatile ............................................................................................................................................ 661
Section 122.6: synchronized .................................................................................................................................. 662
Section 122.7: transient ......................................................................................................................................... 663
Chapter 123: Process .................................................................................................................. 664
Section 123.1: Pitfall: Runtime.exec, Process and ProcessBuilder don't understand shell syntax ....................... 664
Section 123.2: Simple example (Java version < 1.5) ............................................................................................ 666
Chapter 124: Java Native Access .............................................................................................. 667
Section 124.1: Introduction to JNA ........................................................................................................................ 667
Chapter 125: Modules ................................................................................................................. 668
Section 125.1: Defining a basic module ................................................................................................................ 668
Chapter 126: Concurrent Programming (Threads) ................................................................... 669
Section 126.1: Callable and Future ....................................................................................................................... 669
Section 126.2: CountDownLatch ........................................................................................................................... 670
Section 126.3: Basic Multithreading ...................................................................................................................... 672
Section 126.4: Locks as Synchronisation aids ...................................................................................................... 673
Section 126.5: Semaphore .................................................................................................................................... 674
Section 126.6: Synchronization ............................................................................................................................. 675
Section 126.7: Runnable Object ............................................................................................................................ 676
Section 126.8: Creating basic deadlocked system ................................................................................................ 677
Section 126.9: Creating a java.lang.Thread instance ............................................................................................ 679
Section 126.10: Atomic operations ........................................................................................................................ 680
Section 126.11: Exclusive write / Concurrent read access.................................................................................... 681
Section 126.12: Producer-Consumer .................................................................................................................... 682
Section 126.13: Visualizing read/write barriers while using synchronized / volatile .............................................. 684
Section 126.14: Get status of all threads started by your program excluding system threads ............................. 685
Section 126.15: Using ThreadLocal....................................................................................................................... 686
Section 126.16: Multiple producer/consumer example with shared global queue ................................................ 687
Section 126.17: Add two `int` arrays using a Threadpool...................................................................................... 688
Section 126.18: Pausing Execution ....................................................................................................................... 689
Section 126.19: Thread Interruption / Stopping Threads ...................................................................................... 690
Chapter 127: Executor, ExecutorService and Thread pools.................................................... 693
Section 127.1: ThreadPoolExecutor ...................................................................................................................... 693
Section 127.2: Retrieving value from computation - Callable ................................................................................ 694
Section 127.3: submit() vs execute() exception handling di erences ................................................................... 695
Section 127.4: Handle Rejected Execution ........................................................................................................... 697
Section 127.5: Fire and Forget - Runnable Tasks ................................................................................................. 697
Section 127.6: Use cases for di erent types of concurrency constructs ............................................................... 698
Section 127.7: Wait for completion of all tasks in ExecutorService ....................................................................... 699
Section 127.8: Use cases for di erent types of ExecutorService .......................................................................... 701
Section 127.9: Scheduling tasks to run at a fixed time, after a delay or repeatedly .............................................. 703
Section 127.10: Using Thread Pools ..................................................................................................................... 704
Chapter 128: ThreadLocal .......................................................................................................... 705
Section 128.1: Basic ThreadLocal usage .............................................................................................................. 705
Section 128.2: ThreadLocal Java 8 functional initialization ................................................................................... 706
Section 128.3: Multiple threads with one shared object ........................................................................................ 707
Chapter 129: Using ThreadPoolExecutor in MultiThreaded applications. ............................. 709
Section 129.1: Performing Asynchronous Tasks Where No Return Value Is Needed Using a Runnable Class
Instance .......................................................................................................................................................... 709
Section 129.2: Performing Asynchronous Tasks Where a Return Value Is Needed Using a Callable Class
Instance .......................................................................................................................................................... 710
Section 129.3: Defining Asynchronous Tasks Inline using Lambdas .................................................................... 713
Chapter 130: Common Java Pitfalls .......................................................................................... 715
Section 130.1: Pitfall: using == to compare primitive wrappers objects such as Integer ...................................... 715
Section 130.2: Pitfall: using == to compare strings ............................................................................................... 715
Section 130.3: Pitfall: forgetting to free resources ................................................................................................. 717
Section 130.4: Pitfall: testing a file before attempting to open it ............................................................................ 718
Section 130.5: Pitfall: thinking of variables as objects ........................................................................................... 719
Section 130.6: Pitfall: memory leaks...................................................................................................................... 722
Section 130.7: Pitfall: Not understanding that String is an immutable class ......................................................... 723
Section 130.8: Pitfall: combining assignment and side-e ects ............................................................................. 724
Chapter 131: Java Pitfalls - Exception usage ........................................................................... 725
Section 131.1: Pitfall - Catching Throwable, Exception, Error or RuntimeException ............................................ 725
Section 131.2: Pitfall - Ignoring or squashing exceptions ...................................................................................... 726
Section 131.3: Pitfall - Throwing Throwable, Exception, Error or RuntimeException ........................................... 727
Section 131.4: Pitfall - Using exceptions for normal flowcontrol ............................................................................ 728
Section 131.5: Pitfall - Directly subclassing `Throwable`....................................................................................... 729
Section 131.6: Pitfall - Catching InterruptedException .......................................................................................... 729
Section 131.7: Pitfall - Excessive or inappropriate stacktraces ............................................................................. 731
Chapter 132: Java Pitfalls - Language syntax........................................................................... 732
Section 132.1: Pitfall - Missing a ‘break’ in a 'switch' case .................................................................................... 732
Section 132.2: Pitfall - Declaring classes with the same names as standard classes .......................................... 732
Section 132.3: Pitfall - Leaving out braces: the "dangling if" and "dangling else" problems ................................. 733
Section 132.4: Pitfall - Octal literals ....................................................................................................................... 735
Section 132.5: Pitfall - Using '==' to test a boolean ............................................................................................... 735
Section 132.6: Pitfall - Ignoring method visibility ................................................................................................... 736
Section 132.7: Pitfall: Using 'assert' for argument or user input validation............................................................ 736
Section 132.8: Pitfall - Wildcard imports can make your code fragile ................................................................... 737
Section 132.9: Pitfall - Misplaced semicolons and missing braces ....................................................................... 738
Section 132.10: Pitfall - Overloading instead of overriding .................................................................................... 739
Section 132.11: Pitfall of Auto-Unboxing Null Objects into Primitives ................................................................... 740
Chapter 133: Java Pitfalls - Threads and Concurrency ........................................................... 741
Section 133.1: Pitfall - Extending 'java.lang.Thread' ............................................................................................. 741
Section 133.2: Pitfall - Too many threads makes an application slower ............................................................... 742
Section 133.3: Pitfall: incorrect use of wait() / notify() ........................................................................................... 743
Section 133.4: Pitfall: Shared variables require proper synchronization ............................................................... 743
Section 133.5: Pitfall - Thread creation is relatively expensive ............................................................................. 746
Chapter 134: Java Pitfalls - Nulls and NullPointerException................................................... 749
Section 134.1: Pitfall - "Making good" unexpected nulls ....................................................................................... 749
Section 134.2: Pitfall - Using null to represent an empty array or collection ......................................................... 750
Section 134.3: Pitfall - Not checking if an I/O stream isn't even initialized when closing it ................................... 751
Section 134.4: Pitfall - Returning null instead of throwing an exception................................................................ 751
Section 134.5: Pitfall - Unnecessary use of Primitive Wrappers can lead to NullPointerExceptions .................... 752
Section 134.6: Pitfall - Using "Yoda notation" to avoid NullPointerException ....................................................... 753
Chapter 135: Java Pitfalls - Performance Issues ...................................................................... 754
Section 135.1: Pitfall - String concatenation in a loop does not scale ................................................................... 754
Section 135.2: Pitfall - Using size() to test if a collection is empty is ine cient ................................................... 755
Section 135.3: Pitfall - Interning strings so that you can use == is a bad idea ...................................................... 755
Section 135.4: Pitfall - Using 'new' to create primitive wrapper instances is ine cient ...................................... 757
Section 135.5: Pitfall - E ciency concerns with regular expressions ..................................................................... 757
Section 135.6: Pitfall - Small reads / writes on unbu ered streams are ine cient ............................................ 760
Section 135.7: Pitfall - Over-use of primitive wrapper types is ine cient............................................................ 762
Section 135.8: Pitfall - The overheads of creating log messages ......................................................................... 763
Section 135.9: Pitfall - Iterating a Map's keys can be ine cient .......................................................................... 764
Section 135.10: Pitfall - Calling System.gc() is ine cient ...................................................................................... 764
Section 135.11: Pitfall - Calling 'new String(String)' is ine cient ........................................................................... 765
Chapter 136: ServiceLoader ....................................................................................................... 766
Section 136.1: Simple ServiceLoader Example .................................................................................................... 766
Section 136.2: Logger Service ............................................................................................................................... 767
Chapter 137: Classloaders ......................................................................................................... 769
Section 137.1: Implementing a custom classLoader ............................................................................................. 769
Section 137.2: Loading an external .class file ....................................................................................................... 769
Section 137.3: Instantiating and using a classloader ............................................................................................ 770
Chapter 138: Creating Images Programmatically ..................................................................... 772
Section 138.1: Creating a simple image programmatically and displaying it ........................................................ 772
Section 138.2: Save an Image to disk ................................................................................................................... 773
Section 138.3: Setting individual pixel's color in Bu eredImage ........................................................................... 773
Section 138.4: Specifying image rendering quality................................................................................................ 774
Section 138.5: Creating an image with Bu eredImage class ................................................................................ 776
Section 138.6: Editing and re-using image with Bu eredImage ............................................................................ 777
Section 138.7: How to scale a Bu eredImage ...................................................................................................... 778
Chapter 139: Atomic Types ........................................................................................................ 779
Section 139.1: Creating Atomic Types .................................................................................................................. 779
Section 139.2: Motivation for Atomic Types .......................................................................................................... 779
Chapter 140: RSA Encryption .................................................................................................... 783
Section 140.1: An example using a hybrid cryptosystem consisting of OAEP and GCM ..................................... 783
Chapter 141: Secure objects ...................................................................................................... 788
Section 141.1: SealedObject (javax.crypto.SealedObject) .................................................................................... 788
Section 141.2: SignedObject (java.security.SignedObject) ................................................................................... 788
Chapter 142: Security & Cryptography ..................................................................................... 790
Section 142.1: Compute Cryptographic Hashes ................................................................................................... 790
Section 142.2: Encrypt and Decrypt Data with Public / Private Keys .................................................................... 790
Section 142.3: Generate Cryptographically Random Data ................................................................................... 791
Section 142.4: Generate Public / Private Key Pairs .............................................................................................. 791
Section 142.5: Compute and Verify Digital Signatures.......................................................................................... 792
Chapter 143: Security & Cryptography ..................................................................................... 793
Section 143.1: The JCE ......................................................................................................................................... 793
Section 143.2: Keys and Key Management .......................................................................................................... 793
Section 143.3: Common Java vulnerabilities ......................................................................................................... 793
Section 143.4: Networking Concerns .................................................................................................................... 793
Section 143.5: Randomness and You ................................................................................................................... 793
Section 143.6: Hashing and Validation .................................................................................................................. 793
Chapter 144: SecurityManager ................................................................................................... 795
Section 144.1: Sandboxing classes loaded by a ClassLoader .............................................................................. 795
Section 144.2: Enabling the SecurityManager ...................................................................................................... 796
Section 144.3: Implementing policy deny rules ..................................................................................................... 796
Chapter 145: JNDI ....................................................................................................................... 804
Section 145.1: RMI through JNDI .......................................................................................................................... 804
Chapter 146: sun.misc.Unsafe ................................................................................................... 808
Section 146.1: Instantiating sun.misc.Unsafe via reflection .................................................................................. 808
Section 146.2: Instantiating sun.misc.Unsafe via bootclasspath ........................................................................... 808
Section 146.3: Getting Instance of Unsafe ............................................................................................................ 808
Section 146.4: Uses of Unsafe .............................................................................................................................. 809
Chapter 147: Java Memory Model .............................................................................................. 810
Section 147.1: Motivation for the Memory Model .................................................................................................. 810
Section 147.2: Happens-before relationships ........................................................................................................ 812
Section 147.3: How to avoid needing to understand the Memory Model .............................................................. 813
Section 147.4: Happens-before reasoning applied to some examples ................................................................. 814
Chapter 148: Java deployment ................................................................................................... 817
Section 148.1: Making an executable JAR from the command line ...................................................................... 817
Section 148.2: Creating an UberJAR for an application and its dependencies ..................................................... 818
Section 148.3: Creating JAR, WAR and EAR files ................................................................................................ 819
Section 148.4: Introduction to Java Web Start ...................................................................................................... 820
Chapter 149: Java plugin system implementations ................................................................. 823
Section 149.1: Using URLClassLoader ................................................................................................................. 823
Chapter 150: JavaBean ............................................................................................................... 827
Section 150.1: Basic Java Bean ............................................................................................................................ 827
Chapter 151: Java SE 7 Features ............................................................................................... 828
Section 151.1: New Java SE 7 programming language features .......................................................................... 828
Section 151.2: Binary Literals ................................................................................................................................ 828
Section 151.3: The try-with-resources statement .................................................................................................. 828
Section 151.4: Underscores in Numeric Literals ................................................................................................... 829
Section 151.5: Type Inference for Generic Instance Creation .............................................................................. 829
Section 151.6: Strings in switch Statements ......................................................................................................... 829
Chapter 152: Java SE 8 Features ............................................................................................... 831
Section 152.1: New Java SE 8 programming language features .......................................................................... 831
Chapter 153: Dynamic Method Dispatch ................................................................................... 832
Section 153.1: Dynamic Method Dispatch - Example Code .................................................................................. 832
Chapter 154: Generating Java Code .......................................................................................... 835
Section 154.1: Generate POJO From JSON ......................................................................................................... 835
Chapter 155: JShell ..................................................................................................................... 836
Section 155.1: Editting Snippets ............................................................................................................................ 836
Section 155.2: Entering and Exiting JShell ............................................................................................................ 837
Section 155.3: Expressions ................................................................................................................................... 837
Section 155.4: Methods and Classes .................................................................................................................... 838
Section 155.5: Variables ........................................................................................................................................ 838
Chapter 156: Stack-Walking API ................................................................................................ 839
Section 156.1: Print all stack frames of the current thread .................................................................................... 839
Section 156.2: Print current caller class ................................................................................................................ 840
Section 156.3: Showing reflection and other hidden frames ................................................................................. 840
Chapter 157: Sockets .................................................................................................................. 842
Section 157.1: Read from socket........................................................................................................................... 842
Chapter 158: Java Sockets ......................................................................................................... 843
Section 158.1: A simple TCP echo back server .................................................................................................... 843
Chapter 159: FTP (File Transfer Protocol)................................................................................. 846
Section 159.1: Connecting and Logging Into a FTP Server .................................................................................. 846
Chapter 160: Using Other Scripting Languages in Java .......................................................... 851
Section 160.1: Evaluating A JavaScript file in -scripting mode of nashorn ........................................................... 851
Chapter 161: C++ Comparison ................................................................................................... 854
Section 161.1: Static Class Members .................................................................................................................... 854
Section 161.2: Classes Defined within Other Constructs ...................................................................................... 854
Section 161.3: Pass-by-value & Pass-by-reference .............................................................................................. 856
Section 161.4: Inheritance vs Composition ........................................................................................................... 857
Section 161.5: Outcast Downcasting ..................................................................................................................... 857
Section 161.6: Abstract Methods & Classes ......................................................................................................... 857
Chapter 162: Audio ..................................................................................................................... 859
Section 162.1: Play a MIDI file ............................................................................................................................... 859
Section 162.2: Play an Audio file Looped .............................................................................................................. 860
Section 162.3: Basic audio output ......................................................................................................................... 860
Section 162.4: Bare metal sound ........................................................................................................................... 861
Chapter 163: Java Print Service ................................................................................................. 863
Section 163.1: Building the Doc that will be printed .............................................................................................. 863
Section 163.2: Discovering the available print services ........................................................................................ 863
Section 163.3: Defining print request attributes ..................................................................................................... 864
Section 163.4: Listening print job request status change ...................................................................................... 864
Section 163.5: Discovering the default print service.............................................................................................. 866
Section 163.6: Creating a print job from a print service......................................................................................... 866
Chapter 164: CompletableFuture ............................................................................................... 868
Section 164.1: Simple Example of CompletableFuture ......................................................................................... 868
Chapter 165: Runtime Commands ............................................................................................. 869
Section 165.1: Adding shutdown hooks ................................................................................................................ 869
Chapter 166: Unit Testing ........................................................................................................... 870
Section 166.1: What is Unit Testing?..................................................................................................................... 870
Chapter 167: Asserting ............................................................................................................... 873
Section 167.1: Checking arithmetic with assert ..................................................................................................... 873
Chapter 168: Multi-Release JAR Files ....................................................................................... 874
Section 168.1: Example of a multi-release Jar file's contents ............................................................................... 874
Section 168.2: Creating a multi-release Jar using the jar tool ............................................................................... 874
Section 168.3: URL of a loaded class inside a multi-release Jar .......................................................................... 875
Chapter 169: Just in Time (JIT) compiler .................................................................................. 877
Section 169.1: Overview ........................................................................................................................................ 877
Chapter 170: Bytecode Modification ......................................................................................... 879
Section 170.1: What is Bytecode? ......................................................................................................................... 879
Section 170.2: How to edit jar files with ASM ........................................................................................................ 880
Section 170.3: How to load a ClassNode as a Class ............................................................................................ 882
Section 170.4: How to rename classes in a jar file ................................................................................................ 883
Section 170.5: Javassist Basic .............................................................................................................................. 883
Chapter 171: Disassembling and Decompiling......................................................................... 885
Section 171.1: Viewing bytecode with javap ......................................................................................................... 885
Chapter 172: JMX ........................................................................................................................ 892
Section 172.1: Simple example with Platform MBean Server ............................................................................... 892
Chapter 173: Java Virtual Machine (JVM).................................................................................. 896
Section 173.1: These are the basics ..................................................................................................................... 896
Chapter 174: XJC......................................................................................................................... 897
Section 174.1: Generating Java code from simple XSD file .................................................................................. 897
Chapter 175: JVM Flags .............................................................................................................. 900
Section 175.1: -XXaggressive ............................................................................................................................... 900
Section 175.2: -XXallocClearChunks..................................................................................................................... 900
Section 175.3: -XXallocClearChunkSize ............................................................................................................... 900
Section 175.4: -XXcallProfiling .............................................................................................................................. 900
Section 175.5: -XXdisableFatSpin ......................................................................................................................... 901
Section 175.6: -XXdisableGCHeuristics ................................................................................................................ 901
Section 175.7: -XXdumpSize ................................................................................................................................. 901
Section 175.8: -XXexitOnOutOfMemory ................................................................................................................ 902
Chapter 176: JVM Tool Interface ................................................................................................ 903
Section 176.1: Iterate over objects reachable from object (Heap 1.0) .................................................................. 903
Section 176.2: Get JVMTI environment ................................................................................................................. 905
Section 176.3: Example of initialization inside of Agent_OnLoad method ............................................................ 905
Chapter 177: Java Memory Management .................................................................................. 907
Section 177.1: Setting the Heap, PermGen and Stack sizes ................................................................................ 907
Section 177.2: Garbage collection ......................................................................................................................... 908
Section 177.3: Memory leaks in Java .................................................................................................................... 910
Section 177.4: Finalization ..................................................................................................................................... 911
Section 177.5: Manually triggering GC .................................................................................................................. 912
Chapter 178: Java Performance Tuning .................................................................................... 913
Section 178.1: An evidence-based approach to Java performance tuning ........................................................... 913
Section 178.2: Reducing amount of Strings .......................................................................................................... 914
Section 178.3: General approach .......................................................................................................................... 914
Chapter 179: Benchmarks .......................................................................................................... 916
Section 179.1: Simple JMH example ..................................................................................................................... 916
Chapter 180: FileUpload to AWS ................................................................................................ 919
Section 180.1: Upload file to s3 bucket ................................................................................................................. 919
Chapter 181: AppDynamics and TIBCO BusinessWorks Instrumentation for Easy
Integration .................................................................................................................................... 921
Section 181.1: Example of Instrumentation of all BW Applications in a Single Step for Appdynamics ................ 921
Appendix A: Installing Java (Standard Edition) ........................................................................ 922
Section A.1: Setting %PATH% and %JAVA_HOME% after installing on Windows .............................................. 922
Section A.2: Installing a Java JDK on Linux .......................................................................................................... 923
Section A.3: Installing a Java JDK on macOS....................................................................................................... 925
Section A.4: Installing a Java JDK or JRE on Windows ........................................................................................ 926
Section A.5: Configuring and switching Java versions on Linux using alternatives .............................................. 927
Section A.6: What do I need for Java Development .............................................................................................. 928
Section A.7: Selecting an appropriate Java SE release ........................................................................................ 928
Section A.8: Java release and version naming ..................................................................................................... 929
Section A.9: Installing Oracle Java on Linux with latest tar file ............................................................................. 929
Section A.10: Post-installation checking and configuration on Linux .................................................................... 930
Appendix B: Java Editions, Versions, Releases and Distributions ........................................ 933
Section B.1: Di erences between Java SE JRE or Java SE JDK distributions .................................................... 933
Section B.2: Java SE Versions .............................................................................................................................. 934
Section B.3: Di erences between Java EE, Java SE, Java ME and JavaFX ....................................................... 935
Appendix C: The Classpath ........................................................................................................ 937
Section C.1: Di erent ways to specify the classpath ............................................................................................. 937
Section C.2: Adding all JARs in a directory to the classpath ................................................................................. 937
Section C.3: Load a resource from the classpath .................................................................................................. 938
Section C.4: Classpath path syntax ....................................................................................................................... 938
Section C.5: Dynamic Classpath ........................................................................................................................... 939
Section C.6: Mapping classnames to pathnames ................................................................................................. 939
Section C.7: The bootstrap classpath .................................................................................................................... 939
Section C.8: What the classpath means: how searches work ............................................................................... 940
Appendix D: Resources (on classpath) ..................................................................................... 941
Section D.1: Loading default configuration ............................................................................................................ 941
Section D.2: Loading an image from a resource ................................................................................................... 941
Section D.3: Finding and reading resources using a classloader ......................................................................... 941
Section D.4: Loading same-name resource from multiple JARs ........................................................................... 943
1
Chapter 1: Getting started with Java
Language
Java SE Version Code Name End-of-life (free1) Release Date
Java SE 10 (Early Access) None future 2018-03-20
Java SE 9 None future 2017-07-27
Java SE 8 Spider future 2014-03-18
Java SE 7 Dolphin 2015-04-14 2011-07-28
Java SE 6 Mustang 2013-04-16 2006-12-23
Java SE 5 Tiger 2009-11-04 2004-10-04
Java SE 1.4 Merlin prior to 2009-11-04 2002-02-06
Java SE 1.3 Kestrel prior to 2009-11-04 2000-05-08
Java SE 1.2 Playground prior to 2009-11-04 1998-12-08
Java SE 1.1 None prior to 2009-11-04 1997-02-19
Java SE 1.0 Oak prior to 2009-11-04 1996-01-21
Note: For Java to recognize this as a public class (and not throw a compile time error), the filename must be the same
as the class name (HelloWorld in this example) with a .java extension. There should also be a public access modifier
before it.
Naming conventions recommend that Java classes begin with an uppercase character, and be in camel case format (in
which the first letter of each word is capitalized). The conventions recommend against underscores ( _) and dollar signs
($).
cd /path/to/containing/folder/
$ javac HelloWorld.java
It's fairly common to get the error 'javac' is not recognized as an internal or external command, operable program or batch file.
even when you have installed the JDK and are able to run the program from IDE ex. eclipse etc. Since the path is not
added to the environment by default.
Previously when we were calling javac it was same as above command. Only in that case your OS knew where javac
resided. So let's tell it now, this way you don't have to type the whole path every-time. We would need to add this to our
PATH
You cannot undo this so be careful. First copy your existing path to notepad. Then to get the exact PATH to your
javac browse manually to the folder where javac resides and click on the address bar and then copy it. It should look
something like c:\Program Files\Java\jdk1.8.0_xx\bin
In "Variable value" field, paste this IN FRONT of all the existing directories, followed by a semi-colon (;). DO NOT
DELETE any existing entries.
The compiler will then generate a bytecode file called HelloWorld.class which can be executed in the Java Virtual Machine
(JVM). The Java programming language compiler, javac, reads source files written in the Java programming language
and compiles them into bytecode class files. Optionally, the compiler can also process annotations found in source and
class files using the Pluggable Annotation Processing API. The compiler is a command line tool but can also be invoked
using the Java Compiler API.
To run your program, enter java followed by the name of the class which contains the main method (HelloWorld in our
example). Note how the .class is omitted:
$ java HelloWorld
Hello, World!
You have successfully coded and built your very first Java program!
Note: In order for Java commands (java, javac, etc) to be recognized, you will need to make sure:
You will need to use a compiler (javac) and an executor (java) provided by your JVM. To find out which versions you have
installed, enter java -version and javac -version on the command line. The version number of your program will be printed in
the terminal (e.g. 1.8.0_73).
The "Hello World" program contains a single file, which consists of a HelloWorld class definition, a main method, and a
statement inside the main method.
The class keyword begins the class definition for a class named HelloWorld. Every Java application contains at least one
class definition (Further information about classes).
This is an entry point method (defined by its name and signature of public static void main(String[])) from which the JVM
can run your program. Every Java program should have one. It is:
public: meaning that the method can be called from anywhere mean from outside the program as well. See
Visibility for more information on this.
static: meaning it exists and can be run by itself (at the class level without creating an object).
void: meaning it returns no value. Note: This is unlike C and C++ where a return code such as int is expected
(Java's way is System.exit()).
An array (typically called args) of Strings passed as arguments to main function (e.g. from command line
arguments).
Non-required parts:
The name args is a variable name, so it can be called anything you want, although it is typically called args.
Whether its parameter type is an array (String[] args) or Varargs (String... args) does not matter because arrays can
be passed into varargs.
Note: A single application may have multiple classes containing an entry point ( main) method. The entry point of the
application is determined by the class name passed as an argument to the java command.
System.out.println("Hello, World!");
Element Purpose
this denotes that the subsequent expression will call upon the System class, from the java.lang
System
package.
this is the name of a method within the PrintStream class. This method in particular prints the
println
contents of the parameters into the console and inserts a newline after.
this parenthesis indicates that a method is being accessed (and not a field) and begins the
(
parameters being passed into the println method.
"Hello, this is the String literal that is passed as a parameter, into the println method. The double quotation marks
World!" on each end delimit the text as a String.
) this parenthesis signifies the closure of the parameters being passed into the println method.
; this semicolon marks the end of the statement.
Here's another example demonstrating the OO paradigm. Let's model a football team with one (yes, one!) member.
There can be more, but we'll discuss that when we get to arrays.
class Member {
private String name;
private String type;
private int level; // note the data type here private int rank; // note
the data type here as well
public Member(String name, String type, int level, int rank) { this.name = name;
this.type = type;
this.level = level;
this.rank = rank;
}
}
Why do we use private here? Well, if someone wanted to know your name, they should ask you directly, instead of
reaching into your pocket and pulling out your Social Security card. This private does something like that: it prevents
outside entities from accessing your variables. You can only return private members through getter functions (shown
below).
class Member {
private String name;
private String type;
private int level;
private int rank;
public Member(String name, String type, int level, int rank) { this.name = name;
this.type = type;
this.level = level;
this.rank = rank;
}
Output:
Aurieel
light
10
1
Run on ideone
1 - Because the HelloWorld class has little relation to the System class, it can only access public data.
//Implicit casting
byte byteVar = 42;
short shortVar = byteVar;
int intVar = shortVar;
long longVar = intvar;
float floatVar = longVar;
double doubleVar = floatVar;
Explicit casting has to be done when the source type has larger range than the target type.
//Explicit casting
double doubleVar = 42.0d;
float floatVar = (float) doubleVar;
long longVar = (long) floatVar;
int intVar = (int) longVar;
short shortVar = (short) intVar;
byte byteVar = (byte) shortVar;
When casting floating point primitives (float, double) to whole number primitives, the number is rounded down.
A char can be cast to/from any numeric type by using the code-point mappings specified by Unicode. A char is
represented in memory as an unsigned 16-bit integer value (2 bytes), so casting to byte (1 byte) will drop 8 of those bits
(this is safe for ASCII characters). The utility methods of the Character class use int (4 bytes) to transfer to/from code-
point values, but a short (2 bytes) would also suffice for storing a Unicode code-point.
Implicit casting happens when the source type extends or implements the target type (casting to a superclass or
interface).
Explicit casting has to be done when the source type is extended or implemented by the target type (casting to a
subtype). This can produce a runtime exception (ClassCastException) when the object being cast is not of the target
type (or the target's subtype).
In this Person class, there is a single variable: name. This variable can be accessed using the getName() method and
changed using the setName(String) method, however, setting a name requires the new name to have a length greater
than 2 characters and to not be null. Using a setter method rather than making the variable name public allows others to
set the value of name with certain restrictions. The same can be applied to the getter method:
In the modified getName() method above, the name is returned only if its length is less than or equal to 16. Otherwise,
"Name is too large" is returned. This allows the programmer to create variables that are reachable and modifiable
however they wish, preventing client classes from editing the variables unwantedly.
We can't access the count variable because it's private. But we can access the getCount() and the setCount(int) methods
because they are public. To some, this might raise the question; why introduce the middleman? Why not just simply
make they count public?
For all intents and purposes, these two are exactly the same, functionality-wise. The difference between them is the
extensibility. Consider what each class says:
First: "I have a method that will give you an int value, and a method that will set that value to another int".
Second: "I have an int that you can set and get as you please."
These might sound similar, but the first is actually much more guarded in its nature; it only lets you interact with its
internal nature as it dictates. This leaves the ball in its court; it gets to choose how the internal interactions occur. The
second has exposed its internal implementation externally, and is now not only prone to external users, but, in the case
of an API, committed to maintaining that implementation (or otherwise releasing a non-backward-compatible API).
Lets consider if we want to synchronize access to modifying and accessing the count. In the first, this is simple:
but in the second example, this is now nearly impossible without going through and modifying each place where the
count variable is referenced. Worse still, if this is an item that you're providing in a library to be consumed by others, you
do not have a way of performing that modification, and are forced to make the hard choice mentioned above.
So it begs the question; are public variables ever a good thing (or, at least, not evil)?
I'm unsure. On one hand, you can see examples of public variables that have stood the test of time (IE: the out variable
referenced in System.out). On the other, providing a public variable gives no benefit outside of extremely minimal
overhead and potential reduction in wordiness. My guideline here would be that, if you're planning on making a variable
public, you should judge it against these criteria with extreme prejudice:
The variable should have no conceivable reason to ever change in its implementation. This is something that's
extremely easy to screw up (and, even if you do get it right, requirements can change), which is why
getters/setters are the common approach. If you're going to have a public variable, this really needs to be
thought through, especially if released in a library/framework/API.
The variable needs to be referenced frequently enough that the minimal gains from reducing verbosity
warrants it. I don't even think the overhead for using a method versus directly referencing should be
considered here. It's far too negligible for what I'd conservatively estimate to be 99.9% of applications.
There's probably more than I haven't considered off the top of my head. If you're ever in doubt, always use
getters/setters.
These private variables cannot be accessed directly from outside the class. Hence they are protected from
unauthorized access. But if you want to view or modify them, you can use Getters and Setters.
getXxx() method will return the current value of the variable xxx, while you can set the value of the variable xxx using
setXxx().
The naming convention of the methods are (in example variable is called variableName):
getVariableName() //Getter, The variable name should start with uppercase setVariableName(..)
//Setter, The variable name should start with uppercase
boolean variables
isVariableName() //Getter, The variable name should start with uppercase setVariableName(...)
//Setter, The variable name should start with uppercase
Public Getters and Setters are part of the Property definition of a Java Bean.
Dereferencing follows the memory address stored in a reference, to the place in memory where the actual object
resides. When an object has been found, the requested method is called ( toString in this case).
null indicates the absence of a value, i.e. following the memory address leads nowhere. So there is no object on
which the requested method can be called.
Where:
What happens:
int i = 10;
(For an explanation of the above code, please refer to Getting started with Java Language .)
$ javac HelloWorld.java
This produces a file called "HelloWorld.class", which we can then run as follows:
java HelloWorld
Hello world!
The source filename "HelloWorld.java" must match the class name in the source file ... which is HelloWorld. If they
don't match, you will get a compilation error.
The bytecode filename "HelloWorld.class" corresponds to the classname. If you were to rename the
"HelloWorld.class", you would get an error when your tried to run it.
When running a Java application using java, you supply the classname NOT the bytecode filename.
Most practical Java code uses packages to organize the namespace for classes and reduce the risk of accidental
class name collision.
If we wanted to declare the HelloWorld class in a package call com.example, the "HelloWorld.java" would contain the
following Java source:
package com.example;
This source code file needs to stored in a directory tree whose structure corresponds to the package naming.
$ javac com/example/HelloWorld.java
This produces a file called "com/example/HelloWorld.class"; i.e. after compilation, the file structure should look like this:
If your application consists of multiple source code files (and most do!) you can compile them one at a time.
Alternatively, you can compile multiple files at the same time by listing the pathnames:
$ javac *.java
$ javac com/example/*.java
$ javac */**/*.java #Only works on Zsh or with globstar enabled on your shell
This will compile all Java source files in the current directory, in the "com/example" directory, and recursively in child
directories respectively. A third alternative is to supply a list of source filenames (and compiler options) as a file. For
example:
$ javac @sourcefiles
Foo.java
Bar.java
Note: compiling code like this is appropriate for small one-person projects, and for once-off programs. Beyond that, it is
advisable to select and use a Java build tool. Alternatively, most programmers use a Java IDE (e.g. NetBeans, eclipse,
IntelliJ IDEA) which offers an embedded compiler and incremental building of "projects".
Here are a few options for the javac command that are likely to be useful to you
The -d option sets a destination directory for writing the ".class" files.
The -sourcepath option sets a source code search path.
The -cp or -classpath option sets the search path for finding external and previously compiled classes. For more
information on the classpath and how to specify it, refer to the The Classpath Topic.
The -version option prints the compiler's version information.
References
The definitive reference for the javac command is the Oracle manual page for javac.
With very few exceptions (for example the enum keyword, changes to some "internal" classes, etc), these changes are
backwards compatible.
A Java program that was compiled using an older version of the Java toolchain will run on a newer version
Java platform without recompilation.
A Java program that was written in an older version of Java will compile successfully with a new Java compiler.
If you need to (re-)compile older Java code on a newer Java platform to run on the newer platform, you generally don't
need to give any special compilation flags. In a few cases (e.g. if you had used enum as an identifier) you could use the -
source option to disable the new syntax. For example, given the following class:
the following is required to compile the class using a Java 5 compiler (or later):
If you need to compile Java to run on an older Java platforms, the simplest approach is to install a JDK for the oldest
You can also compile with a newer Java compiler, but there are complicated. First of all, there some important
preconditions that must be satisfied:
The code you are compiling must not use Java language constructs that were not available in the version of
Java that you are targeting.
The code must not depend on standard Java classes, fields, methods and so on that were not available in the
older platforms.
Third party libraries that the code depends must also be built for the older platform and available at compile-time
and run-time.
Given the preconditions are met, you can recompile code for an older platform using the -target option. For
example,
will compile the above class to produce bytecodes that are compatible with Java 1.4 or later JVM. (In fact, the -
source option implies a compatible -target, so javac -source 1.4 ... would have the same effect. The relationship
between -source and -target is described in the Oracle documentation.)
Having said that, if you simply use -target or -source, you will still be compiling against the standard class libraries provided
by the compiler's JDK. If you are not careful, you can end up with classes with the correct bytecode version, but with
dependencies on APIs that are not available. The solution is to use the -bootclasspath option. For example:
will compile against an alternative set of runtime libraries. If the class being compiled has (accidental) dependencies on
newer libraries, this will give you compilation errors.
However, these tools are not required to generate the Javadoc HTML; this can be done using the command line
javadoc tool.
javadoc JavaFile.java
A more practical use of the command line tool, which will recursively read all java files in [source-directory], create
documentation for [package.name] and all sub-packages, and place the generated HTML in the [docs-directory] is:
/**
Brief summary of this class, ending with a period.
It is common to leave a blank line between the summary and further details.
The summary (everything before the first period) is used in the class or package
overview section.
*
The following inline tags can be used (not an exhaustive list):
{@link some.other.class.Documentation} for linking to other docs or symbols
{@link some.other.class.Documentation Some Display Name} the link's appearance can be
customized by adding a display name after the doc or symbol locator
{@code code goes here} for formatting as code
{@literal <>[]()foo} for interpreting literal text without converting to HTML markup
or other tags.
*
Optionally, the following tags may be used at the end of class documentation
(not an exhaustive list):
*
@author John Doe
@version 1.0
@since 5/10/15
@see some.other.class.Documentation
@deprecated This class has been replaced by some.other.package.BetterFileReader
*/
public class FileReader {
}
The same tags and format used for Classes can be used for Enums and Interfaces as well.
/**
Brief summary of method, ending with a period.
It is possible to create package-level documentation in Javadocs using a file called package-info.java. This file must be
formatted as below. Leading whitespace and asterisks optional, typically present in each line for formatting reason
/**
Package documentation goes here; any documentation before the first period will
be used as a summary.
*
It is common practice to leave a blank line between the summary and the rest
of the documentation; use this space to describe the package in as much detail
as is appropriate.
*
Inline tags such as {@code code here}, {@link reference.to.other.Documentation},
and {@literal text here} can be used in this documentation.
*/
package com.example.foo;
In the above case, you must put this file package-info.java inside the folder of the Java package com.example.foo.
/**
You can link to the javadoc of an already imported class using {@link ClassName}.
You can also use the fully-qualified name, if the class is not already imported:
{@link some.other.ClassName}
*
You can link to members (fields or methods) of a class like so:
{@link ClassName#someMethod()}
{@link ClassName#someMethodWithParameters(int, String)}
{@link ClassName#someField}
{@link #someMethodInThisClass()} - used to link to members in the current class
/**
This method has a nice explanation but you might found further
information at the bottom.
*
@see ClassName#someMethod()
*/
If you want to add links to external resources you can just use the HTML <a> tag. You can use it inline anywhere or
inside both @link and @see tags.
/**
Wondering how this works? You might want
to check this <a href="http://stackoverflow.com/">great service</a>.
/**
The Class TestUtils.
<p>
This is an {@code inline("code example")}.
<p>
You should wrap it in pre tags when writing multiline code.
<pre>{@code
Example example1 = new FirstLineExample();
example1.butYouCanHaveMoreThanOneLine();
}</pre>
<p>
Thanks for reading.
*/
class TestUtils {
Sometimes you may need to put some complex code inside the javadoc comment. The @ sign is specially
problematic. The use of the old <code> tag alongside the {@literal } construct solves the problem.
/**
Usage:
<pre><code>
class SomethingTest {
{@literal @}Rule
{@literal @}Test
public void test1() {
// only this test will be executed
}
*
...
}
</code></pre>
*/
class SingleTestRule implements TestRule { }
/**
Fields can be documented as well.
As with other javadocs, the documentation before the first period is used as a
summary, and is usually separated from the rest of the documentation by a blank
line.
*
Documentation for fields can use inline tags, such as:
{@code code here}
{@literal text here}
{@link other.docs.Here}
*
Field documentation can also make use of the following tags:
@since 2.1.0
@see some.other.class.Documentation
@deprecated Describe why this field is outdated
*/
public static final String CONSTANT_STRING = "foo";
Single Line comments are started by // and may be positioned after a statement on the same line, but not before.
Multi-Line comments are defined between /* and */. They can span multiple lines and may even been positioned
between statements.
/*
As too many inline comments may decrease readability of code, they should be used sparsely in case the code isn't self-
explanatory enough or the design decision isn't obvious.
An additional use case for single-line comments is the use of TAGs, which are short, convention driven keywords. Some
development environments recognize certain conventions for such single-comments. Common examples are
//TODO
//FIXME
//PRJ-1234
https://gwt.googlesource.com/gwt/+/2.8.0-beta1/dev/core/src/com/google/gwt/util/tools/ToolBase.java
An example for handling the command-line myprogram -dir "~/Documents" -port 8888 is:
public MyProgramHandler() {
this.registerHandler(new ArgHandlerDir() {
@Override
public void setDir(File dir) {
this.dir = dir;
}
});
this.registerHandler(new ArgHandlerInt() {
@Override
public String[] getTagArgs() {
return new String[]{"port"};
}
@Override
public void setInt(int value) {
this.port = value;
}
});
}
public static void main(String[] args) { MyProgramHandler myShell =
new MyProgramHandler(); if (myShell.processArgs(args)) {
ArgHandler also has a method isRequired() which can be overwritten to say that the command-line argument is required
(default return is false so that the argument is optional.
In this example, we will present a series of simple case studies. In each case, the code will produce error messages if
the arguments are unacceptable, and then call System.exit(1) to tell the shell that the command has failed. (We will
assume in each case that the Java code is invoked using a wrapper whose name is "myapp".)
In this case-study, the command requires no arguments. The code illustrates that args.length gives us the number of
command line arguments.
Note that if we neglected to check args.length, the command would crash if the user ran it with too few
command-line arguments.
In this case-study, the command has a couple of (optional) flag options, and requires at least one argument after the
options.
package tommy;
public class Main {
public static void main(String[] args) {
boolean feelMe = false;
boolean seeMe = false;
int index;
loop: for (index = 0; index < args.length; index++) { String opt =
args[index];
switch (opt) {
case "-c":
seeMe = true;
break;
case "-f":
}
}
As you can see, processing the arguments and options gets rather cumbersome if the command syntax is
complicated. It is advisable to use a "command line parsing" library; see the other examples.
When the java command starts the virtual machine, it loads the specified entry-point classes and tries to find main.
If successful, the arguments from command line are converted to Java String objects and assembled into an array.
If main is invoked like this, the array will not be null and won't contain any null entries.
It is conventional to declare the class as public but this not strictly necessary. From Java 5 onward, the main method's
argument type may be a String varargs instead of a string array. main can optionally throw exceptions, and its
parameter can be named anything, but conventionally it is args.
JavaFX entry-points
From Java 8 onwards the java command can also directly launch a JavaFX application. JavaFX is documented in the
JavaFX tag, but a JavaFX entry-point must do the following:
Extend javafx.application.Application
Be public and not abstract
Not be generic or nested
Have an explicit or implicit public no-args constructor
when trying to run the java command, this means that there is no java command on your shell's command search path.
The cause could be:
Refer to "Installing Java" for the steps that you need to take.
This error message is output by the java command if it has been unable to find / load the entry-point class that you have
specified. In general terms, there are three broad reasons that this can happen:
You have specified an entry point class that does not exist.
The class exists, but you have specified it incorrectly.
The class exists and you have specified it correctly, but Java cannot it find it because the classpath is
incorrect.
If you have source code for a class, then the full name consists of the package name and the simple class
name. The instance the "Main" class is declared in the package "com.example.myapp" then its full name is
"com.example.myapp.Main".
If you have a compiled class file, you can find the class name by running javap on it.
If the class file is in a directory, you can infer the full class name from the directory names.
If the class file is in a JAR or ZIP file, you can infer the full class name from the file path in the JAR or ZIP
file.
Look at the error message from the java command. The message should end with the full class name that java
is trying to use.
Check that it exactly matches the full classname for the entry-point class.
It should not end with ".java" or ".class".
It should not contain slashes or any other character that is not legal in a Java identifier1.
The casing of the name should exactly match the full class name.
3. If you are using the correct classname, make sure that the class is actually on the classpath:
Work out the pathname that the classname maps to; see Mapping classnames to pathnames
Work out what the classpath is; see this example: Different ways to specify the classpath
Look at each of the JAR and ZIP files on the classpath to see if they contain a class with the required
pathname.
Look at each directory to see if the pathname resolves to a file within the directory.
If checking the classpath by hand did not find the issue, you could add the -Xdiag and -XshowSettings options. The former
lists all classes that are loaded, and the latter prints out settings that include the effective classpath for the JVM.
An executable JAR file with a Main-Class attribute that specifies a class that does not exist.
An executable JAR file with an incorrect Class-Path attribute.
If you mess up2 the options before the classname, the java command may attempt to interpret one of them
This problem happens when the java command is able to find and load the class that you nominated, but is then unable
to find an entry-point method.
If you are trying to run an executable JAR file, then the JAR's manifest has an incorrect "Main-Class" attribute that
specifies a class that is not a valid entry point class.
You have told the java command a class that is not an entry point class.
The entry point class is incorrect; see Entry point classes for more information.
Other Resources
1 - From Java 8 and later, the java command will helpfully map a filename separator ("/" or "") to a period (".").
However, this behavior is not documented in the manual pages.
2 - A really obscure case is if you copy-and-paste a command from a formatted document where the text editor has used
a "long hyphen" instead of a regular hyphen.
Typical Java applications consist of an application-specific code, and various reusable library code that you have
implemented or that has been implemented by third parties. The latter are commonly referred to as library
dependencies, and are typically packaged as JAR files.
Java is a dynamically bound language. When you run a Java application with library dependencies, the JVM needs to
know where the dependencies are so that it can load classes as required. Broadly speaking, there are two ways to deal
with this:
The application and its dependencies can be repackaged into a single JAR file that contains all of the required
classes and resources.
The JVM can be told where to find the dependent JAR files via the runtime classpath.
For an executable JAR file, the runtime classpath is specified by the "Class-Path" manifest attribute. (Editorial Note:
This should be described in a separate Topic on the jar command.) Otherwise, the runtime classpath needs to be
supplied using the -cp option or using the CLASSPATH environment variable.
For example, suppose that we have a Java application in the "myApp.jar" file whose entry point class is
com.example.MyApp. Suppose also that the application depends on library JAR files "lib/library1.jar" and
"lib/library2.jar". We could launch the application using the java command as follows in a command line:
$ # Alternative 1 (preferred)
$ # Alternative 2
export CLASSPATH=myApp.jar:lib/library1.jar:lib/library2.jar
java com.example.MyApp
(On Windows, you would use ; instead of : as the classpath separator, and you would set the (local) CLASSPATH
variable using set rather than export.)
While a Java developer would be comfortable with that, it is not "user friendly". So it is common practice to write a
simple shell script (or Windows batch file) to hide the details that the user doesn't need to know about. For example, if
you put the following shell script into a file called "myApp", made it executable, and put it into a directory on the
command search path:
#!/bin/bash
# The 'myApp' wrapper script
export DIR=/usr/libexec/myApp
export CLASSPATH=$DIR/myApp.jar:$DIR/lib/library1.jar:$DIR/lib/library2.jar java
com.example.MyApp
Any arguments on the command line will be passed to the Java application via the "$@" expansion. (You can do
something similar with a Windows batch file, though the syntax is different.)
All options start with a single hyphen or minus-sign (-): the GNU/Linux convention of using -- for "long"
options is not supported.
Options must appear before the <classname> or the -jar <jarfile> argument to be recognized. Any arguments
after them will be treated as arguments to be passed to Java app that is being run.
Options that do not start with -X or -XX are standard options. You can rely on all Java implementations1 to
support any standard option.
Options that start with -X are non-standard options, and may be withdrawn from one Java version to the next.
Options that start with -XX are advanced options, and may also be withdrawn.
The -D<property>=<value> option is used to set a property in the system Properties object. This parameter can be repeated
to set different properties.
The main options for controlling the heap and stack sizes are documented in Setting the Heap, PermGen and Stack
sizes. (Editorial note: Garbage Collector options should be described in the same topic.)
The -ea and -da options respectively enable and disable Java assert checking:
Note that enabling to assertion checking is liable to alter the behavior of a Java programming.
The -client and -server options allow you to select between two different forms of the HotSpot VM:
The "client" form is tuned for user applications and offers faster startup.
The "server" form is tuned for long running applications. It takes longer capturing statistic during JVM "warm up"
which allows the JIT compiler to do a better of job of optimizing the native code.
By default, the JVM will run in 64bit mode if possible, depending on the capabilities of the platform. The -d32 and - d64
options allow you to select the mode explicitly.
1 - Check the official manual for the java command. Sometimes a standard option is described as "subject to
change".
As an example, let us suppose that we have the following simple program that prints the size of a file:
import java.io.File;
Now suppose that we want print the size of a file whose pathname has spaces in it; e.g. /home/steve/Test File.txt.
If we run the command like this:
the shell won't know that /home/steve/Test File.txt is actually one pathname. Instead, it will pass 2 distinct arguments to
the Java application, which will attempt to find their respective file sizes, and fail because files with those paths
(probably) do not exist.
POSIX shells include sh as well derivatives such as bash and ksh. If you are using one of these shells, then you can
solve the problem by quoting the argument.
The double-quotes around the pathname tell the shell that it should be passed as a single argument. The quotes will
be removed when this happens. There are a couple of other ways to do this:
Single (straight) quotes are treated like double-quotes except that they also suppress various expansions within the
argument.
A backslash escapes the following space, and causes it not to be interpreted as an argument separator.
For more comprehensive documentation, including descriptions of how to deal with other special characters in
arguments, please refer to the quoting topic in the Bash documentation.
The fundamental problem for Windows is that at the OS level, the arguments are passed to a child process as a single
string (source). This means that the ultimate responsibility of parsing (or re-parsing) the command line falls on either
program or its runtime libraries. There is lots of inconsistency.
You can put double-quotes around an argument in a java command, and that will allow you to pass
arguments with spaces in them.
Apparently, the java command itself is parsing the command string, and it gets it more or less right
However, when you try to combine this with the use of SET and variable substitution in a batch file, it gets really
complicated as to whether double-quotes get removed.
Assuming that you have an executable JAR file with pathname <jar-path>, you should be able to run it as follows:
If the command requires command-line arguments, add them after the <jar-path>. For example:
If you need to provide additional JVM options on the java command line, they need to go before the -jar option. Note that a
-cp / -classpath option will be ignored if you use -jar. The application's classpath is determined by the JAR file manifest.
The "HelloWorld" example is described in Creating a new Java program . It consists of a single class called
HelloWorld which satisfies the requirements for an entry-point.
Assuming that the (compiled) "HelloWorld.class" file is in the current directory, it can be launched as follows:
java HelloWorld
We must provide the name of the class: not the pathname for the ".class" file or the ".java" file.
If the class is declared in a package (as most Java classes are), then the class name we supply to the java
command must be the full classname. For instance if SomeClass is declared in the com.example package, then the
full classname will be com.example.SomeClass.
Specifying a classpath
Unless we are using in the java -jar command syntax, the java command looks for the class to be loaded by searching the
classpath; see The Classpath. The above command is relying on the default classpath being (or including) the current
directory. We can be more explicit about this by specifying the classpath to be used using the -cp option.
This says to make the current directory (which is what "." refers to) the sole entry on the classpath.
(If no -cp option is provided, the java will use the classpath that is given by the CLASSPATH environment variable. If that
variable is unset or empty, java uses "." as the default classpath.)
Version ≥ Java SE 7
int i1 = 123456;
int i2 = 123_456;
System.out.println(i1 == i2); // true
Version ≥ Java SE 7
byte color = 1_2_3;
short yearsAnnoDomini= 2_016;
int socialSecurtyNumber = 999_99_9999;
long creditCardNumber = 1234_5678_9012_3456L;
float piFourDecimals = 3.14_15F;
double piTenDecimals = 3.14_15_92_65_35;
This also works using prefixes for binary, octal and hexadecimal bases:
Version ≥ Java SE 7
short binary= 0b0_1_0_1;
int octal = 07_7_7_7_7_7_7_7_0;
long hexBytes = 0xFF_EC_DE_5E;
There are a few rules about underscores which forbid their placement in the following places:
At the beginning or end of a number (e.g. _123 or 123_ are not valid)
Adjacent to a decimal point in a floating point literal (e.g. 1._23 or 1_.23 are not valid)
Prior to an F or L suffix (e.g. 1.23_F or 9999999_L are not valid)
In positions where a string of digits is expected (e.g. 0_xFFFF is not valid)
The octal literal can easily be a trap for semantic errors. If you define a leading '0' to your decimal literals you will get the
wrong value:
For example:
Note that a single string literal may not span multiple source code lines. It is a compilation error for a line-break (or the
end of the source file) to occur before a literal's closing double-quote. For example:
Long strings
If you need a string that is too long to fit on a line, the conventional way to express it is to split it into multiple
literals and use the concatenation operator (+) to join the pieces. For example
An expression like the above consisting of string literals and + satisfies the requirements to be a Constant
Expression. That means that the expression will be evaluated by the compiler and represented at runtime by a
single String object.
For more information on interning and the string pool, refer to the String pool and heap storage example in the
Strings topic.
myMethod(null);
if (objects != null) {
// Do something
}
The null type is rather unusual. It has no name, so you cannot express it in Java source code. (And it has no runtime
representation either.)
The sole purpose of the null type is to be the type of null. It is assignment compatible with all reference types, and can
be type cast to any reference type. (In the latter case, the cast does not entail a runtime type check.)
Finally, null has the property that null instanceof <SomeReferenceType> will evaluate to false, no matter what the type is.
The <octal> in the above consists of one, two or three octal digits ('0' through '7') which represent a number
between 0 and 255 (decimal).
Note that a backslash followed by any other character is an invalid escape sequence. Invalid escape sequences are
treated as compilation errors by the JLS.
Unicode escapes
In addition to the string and character escape sequences described above, Java has a more general Unicode
escaping mechanism, as defined in JLS 3.3. Unicode Escapes. A Unicode escape has the following syntax:
where <hex-digit> is one of '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'.
A Unicode escape is mapped by the Java compiler to a character (strictly speaking a 16-bit Unicode code unit), and
can be used anywhere in the source code where the mapped character is valid. It is commonly used in character and
string literals when you need to represent a non-ASCII character in a literal.
Escaping in regexes
TBD
For example:
char a = 'a';
char doubleQuote = '"';
char singleQuote = '\'';
The simplest and most common form of integer literal is a decimal integer literal. For example:
You need to be careful with leading zeros. A leading zero causes an integer literal to be interpreted as octal not
decimal.
Integer literals are unsigned. If you see something like -10 or +10, these are actually expressions using the unary - and
unary + operators.
The range of integer literals of this form have an intrinsic type of int, and must fall in the range zero to 231 or
2,147,483,648.
Note that 231 is 1 greater than Integer.MAX_VALUE. Literals from 0 through to 2147483647 can be used anywhere, but it is
a compilation error to use 2147483648 without a preceding unary - operator. (In other words, it is reserved for expressing
the value of Integer.MIN_VALUE.)
Note that the distinction between int and long literals is significant in other places. For example
int i = 2147483647;
long l = i + 1; // Produces a negative value because the operation is
// performed using 32 bit arithmetic, and the
// addition overflows
long l2 = i + 1L; // Produces the (intuitively) correct value.
(The JLS syntax rules combine the two decimal forms into a single form. We treat them separately for ease of
explanation.)
The simplest form of floating point literal consists of one or more decimal digits and a decimal point ( .) and an optional
suffix (f, F, d or D). The optional suffix allows you to specify that the literal is a float (f or F) or double (d or D) value. The
default (when no suffix is specified) is double.
For example
The meaning of a decimal literal is the IEEE floating point number that is closest to the infinite precision mathematical
Real number denoted by the decimal floating point form. This conceptual value is converted to IEEE binary floating point
representation using round to nearest. (The precise semantics of decimal conversion are specified in the javadocs for
Double.valueOf(String) and Float.valueOf(String), bearing in mind that there are differences in the number syntaxes.)
Scaled decimal forms consist of simple decimal with an exponent part introduced by an E or e, and followed by a
signed integer. The exponent part is a short hand for multiplying the decimal form by a power of ten, as shown in the
examples below. There is also an optional suffix to distinguish float and double literals. Here are some examples:
The size of a literal is limited by the representation (float or double). It is a compilation error if the scale factor results
in a value that is too large or too small.
Hexadecimal forms
Starting with Java 6, it is possible to express floating point literals in hexadecimal. The hexadecimal form have an
analogous syntax to the simple and scaled decimal forms with the following differences:
Every hexadecimal floating point literal starts with a zero ( 0) and then an x or X.
The digits of the number (but not the exponent part!) also include the hexadecimal digits a through f and their
uppercase equivalents.
The exponent is mandatory, and is introduced by the letter p (or P) instead of an e or E. The exponent
represents a scaling factor that is a power of 2 instead of a power of 10.
Advice: since hexadecimal floating-point forms are unfamiliar to most Java programmers, it is advisable to use them
sparingly.
Underscores
Starting with Java 7, underscores are permitted within the digit strings in all three forms of floating point literal. This
applies to the "exponent" parts as well. See Using underscores to improve readability.
Special cases
It is a compilation error if a floating point literal denotes a number that is too large or too small to represent in the
selected representation; i.e. if the number would overflow to +INF or -INF, or underflow to 0.0. However, it is legal for a
literal to represent a non-zero denormalized number.
The floating point literal syntax does not provide literal representations for IEEE 754 special values such as the INF and
NaN values. If you need to express them in source code, the recommended way is to use the constants defined by the
java.lang.Float and java.lang.Double; e.g. Float.NaN, Float.NEGATIVE_INFINITY and Float.POSITIVE_INFINITY.
It has a minimum value of \u0000 (0 in the decimal representation, also called the null character) and a maximum value
of \uffff (65,535).
In order to define a char of ' value an escape sequence (character preceded by a backslash) has to be used:
char unicodeChar = '\uXXXX' // XXXX represents the Unicode-value of the character you want to display
It is also possible to add to a char. e.g. to iterate through every lower-case letter, you could do to the following:
default
data type numeric representation range of values
value
Notes:
The Java Language Specification mandates that signed integral types ( byte through long) use binary twos-
complement representation, and the floating point types use standard IEE 754 binary floating point
representations.
Java 8 and later provide methods to perform unsigned arithmetic operations on int and long. While these
methods allow a program to treat values of the respective types as unsigned, the types remain signed types.
The smallest floating point shown above are subnormal; i.e. they have less precision than a normal value. The
smallest normal numbers are 1.175494351e−38 and 2.2250738585072014e−308
A char conventionally represents a Unicode / UTF-16 code unit.
Although a boolean contains just one bit of information, its size in memory varies depending on the Java
Virtual Machine implementation (see boolean type).
Floats handle the five common arithmetical operations: addition, subtraction, multiplication, division, and modulus.
Note: The following may vary slightly as a result of floating point errors. Some results have been rounded for clarity
and readability purposes (i.e. the printed result of the addition example was actually 34.600002).
// addition
float result = 37.2f + -2.6f; // result: 34.6
// subtraction
float result = 45.1f - 10.3f; // result: 34.8
// division
float result = 37.1f / 4.8f; // result: 7.729166
// modulus
float result = 37.1f % 4.8f; // result: 3.4999971
Because of the way floating point numbers are stored (i.e. in binary form), many numbers don't have an exact
representation.
While using float is fine for most applications, neither float nor double should be used to store exact representations
of decimal numbers (like monetary amounts), or numbers where higher precision is required. Instead, the
BigDecimal class should be used.
Note: Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NaN are float values. NaN stands for results of operations
that cannot be determined, such as dividing 2 infinite values. Furthermore 0f and -0f are different, but
yields true:
float f1 = 0f;
float f2 = -0f;
System.out.println(f1 == f2); // true
System.out.println(1f / f1); // Infinity
System.out.println(1f / f2); // -Infinity
System.out.println(Float.POSITIVE_INFINITY / Float.POSITIVE_INFINITY); // NaN
According to java API: "The Integer class wraps a value of the primitive type int in an object. An object of type
Integer contains a single field whose type is int."
By default, int is a 32-bit signed integer. It can store a minimum value of -231, and a maximum value of 231 - 1.
If you need to store a number outside of this range, long should be used instead. Exceeding the value range of int leads
to an integer overflow, causing the value exceeding the range to be added to the opposite site of the range (positive
becomes negative and vise versa). The value is ((value - MIN_VALUE) % RANGE) + MIN_VALUE, or ((value
There are two types of conversions: widening conversion and narrowing conversion.
A widening conversion is when a value of one datatype is converted to a value of another datatype that occupies
more bits than the former. There is no issue of data loss in this case.
Correspondingly, A narrowing conversion is when a value of one datatype is converted to a value of another
datatype that occupies fewer bits than the former. Data loss can occur in this case.
Java performs widening conversions automatically. But if you want to perform a narrowing conversion (if you are sure
that no data loss will occur), then you can force Java to perform the conversion using a language construct known as a
cast.
Widening Conversion:
int a = 1;
double d = a; // valid conversion to double, no cast needed (widening)
Narrowing Conversion:
double d = 18.96
int b = d; // invalid conversion to int, will throw a compile-time error
int b = (int) d; // valid conversion to int, but result is truncated (gets rounded down)
This is type-casting
Now, b = 18
Boxed objects always require 8 bytes for type and memory management, and because the size of objects is always a
multiple of 8, boxed types all require 16 bytes total. In addition, each usage of a boxed object entails storing a reference
which accounts for another 4 or 8 bytes, depending on the JVM and JVM options.
In data-intensive operations, memory consumption can have a major impact on performance. Memory consumption
grows even more when using arrays: a float[5] array will require only 32 bytes; whereas a Float[5] storing 5 distinct non-
null values will require 112 bytes total (on 64 bit without compressed pointers, this increases to 152 bytes).
The space overheads of the boxed types can be mitigated to a degree by the boxed value caches. Some of the boxed
types implement a cache of instances. For example, by default, the Integer class will cache instances to represent
numbers in the range -128 to +127. This does not, however, reduce the additional cost arising from the additional
memory indirection.
If you create an instance of a boxed type either by autoboxing or by calling the static valueOf(primitive) method, the
runtime system will attempt to use a cached value. If your application uses a lot of values in the range that is cached,
then this can substantially reduce the memory penalty of using boxed types. Certainly, if you are creating boxed value
instances "by hand", it is better to use valueOf rather than new. (The new operation always creates a new instance.) If,
however, the majority of your values are not in the cached range, it can be faster to call new and save the cache lookup.
Because of the way floating point numbers are stored, many numbers don't have an exact representation.
While using double is fine for most applications, neither float nor double should be used to store precise numbers such as
currency. Instead, the BigDecimal class should be used
double d1 = 0d;
double d2 = -0d;
System.out.println(d1 == d2); // true
System.out.println(1d / d1); // Infinity
System.out.println(1d / d2); // -Infinity
System.out.println(Double.POSITIVE_INFINITY / Double.POSITIVE_INFINITY); // NaN
//an "L" must be appended to the end of the number, because by default, //numbers are assumed
to be the int type. Appending an "L" makes it a long
//as 549755813888 (2 ^ 39) is larger than the maximum value of an int (2^31 - 1), //"L" must be appended
Note: letter "L" appended at the end of long literal is case insensitive, however it is good practice to use capital as it is
easier to distinct from digit one:
2L == 2l; // true
Warning: Java caches Integer objects instances from the range -128 to 127. The reasoning is explained here:
https://blogs.oracle.com/darcy/entry/boxing_and_caches_integer_valueof
To properly compare 2 Object Long values, use the following code(From Java 1.7 onward):
Comparing a primitive long to an Object long will not result in a false negative like comparing 2 objects with ==
does.
For a unique binary representation of a data type using n bits, values are encoded like this:
The least significant n-1 bits store a positive integral number x in integral representation. Most significant value stores
a bit vith value s. The value repesented by those bits is
x - s * 2n-1
i.e. if the most significant bit is 1, then a value that is just by 1 larger than the number you could represent with the other
bits (2n-2 + 2n-3 + ... + 21 + 20 = 2n-1 - 1) is subtracted allowing a unique binary representation for each value from - 2n-1
(s = 1; x = 0) to 2n-1 - 1 (s = 0; x = 2n-1 - 1).
This also has the nice side effect, that you can add the binary representations as if they were positive binary
numbers:
v1 = x1 - s1 * 2n-1 v2 = x2 - s2 * 2n-1
s1 s2 x1 + x2 overflow addition result
0 0 No x1 + x2 = v1 + v2
0 0 Yes too large to be represented with data type (overflow)
x1 + x2 - 2n-1 = x1 + x2 - s2 * 2n-1
0 1 No
= v1 + v2
(x1 + x2) mod 2n-1 = x1 + x2 - 2n-1
0 1 Yes
= v1 + v2
1 0* see above (swap summands)
1 1 No too small to be represented with data type (x1 + x2 - 2n < -2n-1 ; underflow)
(x1 + x2) mod 2n-1 - 2n-1 = (x1 + x2 - 2n-1) - 2n-1
1 1 Yes = (x1 - s1 * 2n-1) + (x2 - s2 * 2n-1)
= v1 + v2
Note that this fact makes finding binary representation of the additive inverse (i.e. the negative value) easy:
Observe that adding the bitwise complement to the number results in all bits being 1. Now add 1 to make value
overflow and you get the neutral element 0 (all bits 0).
So the negative value of a number i can be calculated using (ignoring possible promotion to int here)
(~i) + 1
The result of negating 0, is 11111111. Adding 1 gives a value of 100000000 (9 bits). Because a byte can only store 8
bits, the leftmost value is truncated, and the result is 00000000
In Java, Strings are immutable, meaning that they cannot be changed. (Click here for a more thorough explanation of
immutability.)
For example, the following snippet will determine if the two instances of String are equal on all characters:
if (firstString.equals(secondString)) {
// Both Strings have the same content.
}
Live demo
if (firstString.equalsIgnoreCase(secondString)) {
// Both Strings are equal, ignoring the case of the individual characters.
}
Live demo
Note that equalsIgnoreCase does not let you specify a Locale. For instance, if you compare the two words "Taki" and "TAKI"
in English they are equal; however, in Turkish they are different (in Turkish, the lowercase I is ı). For cases like this,
converting both strings to lowercase (or uppercase) with Locale and then comparing with equals is the solution.
System.out.println(firstString.toLowerCase(locale).equals(
secondString.toLowerCase(locale))); //prints false
Live demo
Unless you can guarantee that all strings have been interned (see below), you should not use the == or !=
Instead, use the String.equals(Object) method, which will compare the String objects based on their values. For a detailed
explanation, please refer to Pitfall: using == to compare strings.
As of Java 1.7, it is possible to compare a String variable to literals in a switch statement. Make sure that the String is
not null, otherwise it will always throw a NullPointerException. Values are compared using String.equals, i.e. case sensitive.
switch (stringToSwitch) {
case "a":
System.out.println("a");
break;
case "A":
System.out.println("A"); //the code goes here
break;
case "B":
System.out.println("B");
break;
default:
break;
}
Live demo
When comparing a String to a constant value, you can put the constant value on the left side of equals to ensure that
you won't get a NullPointerException if the other String is null.
"baz".equals(foo)
While foo.equals("baz") will throw a NullPointerException if foo is null, "baz".equals(foo) will evaluate to false.
Version ≥ Java SE 7
A more readable alternative is to use Objects.equals(), which does a null check on both parameters:
Objects.equals(foo, "baz").
(Note: It is debatable as to whether it is better to avoid NullPointerExceptions in general, or let them happen and then fix
the root cause; see here and here. Certainly, calling the avoidance strategy "best practice" is not justifiable.)
String orderings
The String class implements Comparable<String> with the String.compareTo method (as described at the start of this
example). This makes the natural ordering of String objects case-sensitive order. The String class provide a
Comparator<String> constant called CASE_INSENSITIVE_ORDER suitable for case-insensitive sorting.
"Moreover, a string literal always refers to the same instance of class String. This is because string literals
or, more generally, strings that are the values of constant expressions - are interned so as to share
unique instances, using the method String.intern."
This means it is safe to compare references to two string literals using ==. Moreover, the same is true for references to
String objects that have been produced using the String.intern() method.
For example:
The two string references point two strings that are equal if
(strObj.equals(str)) {
System.out.println("The strings are equal");
}
The two string references do not point to the same object if (strObj != str) {
if (internedStr == str) {
System.out.println("The interned string and the literal are the same object");
}
Behind the scenes, the interning mechanism maintains a hash table that contains all interned strings that are still
reachable. When you call intern() on a String, the method looks up the object in the hash table:
If the string is found, then that value is returned as the interned string.
Otherwise, a copy of the string is added to the hash table and that string is returned as the interned string.
It is possible to use interning to allow strings to be compared using ==. However, there are significant problems with
doing this; see Pitfall - Interning strings so that you can use == is a bad idea for details. It is not recommended in most
cases.
These methods both return the converted strings as new String instances: the original String objects are not
modified because String is immutable in Java. See this for more on immutability : Immutability of Strings in Java
Non-alphabetic characters, such as digits and punctuation marks, are unaffected by these methods. Note that these
methods may also incorrectly deal with certain Unicode characters under certain conditions.
Note: These methods are locale-sensitive, and may produce unexpected results if used on strings that are intended to
be interpreted independent of the locale. Examples are programming language identifiers, protocol keys, and HTML tags.
For instance, "TITLE".toLowerCase() in a Turkish locale returns "tıtle", where ı (\u0131) is the LATIN SMALL LETTER
DOTLESS I character. To obtain correct results for locale insensitive strings, pass Locale.ROOT as a parameter to
the corresponding case converting method (e.g. toLowerCase(Locale.ROOT) or toUpperCase(Locale.ROOT)).
Although using Locale.ENGLISH is also correct for most cases, the language invariant way is Locale.ROOT.
A detailed list of Unicode characters that require special casing can be found on the Unicode Consortium website.
To change the case of a specific character of an ASCII string following algorithm can be used:
Steps:
Declare a string.
Input the string.
Convert the string into a character array.
Input the character that is to be searched.
Search for the character into the character array.
If found,check if the character is lowercase or uppercase.
If Uppercase, add 32 to the ASCII code of the character.
If Lowercase, subtract 32 from the ASCII code of the character.
Change the original character from the Character array.
Convert the character array back into the string.
}
a[i] = d;
break;
}
}
s = String.valueOf(a);
System.out.println(s);
The String.contains() method can be used to verify if a CharSequence can be found in the String. The method looks for
the String a in the String b in a case-sensitive way.
To find the exact position where a String starts within another String, use String.indexOf():
The String.indexOf() method returns the first index of a char or String in another String. The method returns -1 if it is not
found.
class Strings
{
public static void main (String[] args)
{
String a = "alpha";
String b = "alpha";
String c = new String("alpha");
}
}
true
true
true
true
However using new operator, we force String class to create a new String object in heap space. We can use intern()
method to put it into the pool or refer to other String object from string pool having same value.
Before Java 7, String literals were stored in the runtime constant pool in the method area of PermGen, that had a fixed
size.
Version ≥ Java SE 7
RFC: 6962931
In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are
instead allocated in the main part of the Java heap (known as the young and old generations), along with the
other objects created by the application. This change will result in more data residing in the main Java heap,
and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications
will see only relatively small differences in heap usage due to this change, but larger applications that load
many classes or make heavy use of the String.intern() method will see more significant differences.
Note that delimiting character or regular expression gets removed from the resulting String Array.
In the previous example . is treated as the regular expression wildcard that matches any character, and since every
character is a delimiter, the result is an empty array.
>-=!()[]{}\^$|?*+.
To split a string based on one of the above delimiters, you need to either escape them using \\ or use
Pattern.quote():
Using Pattern.quote():
String s = "a|b|c";
String regex = Pattern.quote("|");
String[] arr = s.split(regex);
String s = "a|b|c";
String[] arr = s.split("\\|");
split(delimiter) by default removes trailing empty strings from result array. To turn this mechanism off we need to use
overloaded version of split(delimiter, limit) with limit set to negative value like
The limit parameter controls the number of times the pattern is applied and therefore affects the length of the
resulting array.
If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's length will be no
greater than n, and the array's last entry will contain all input beyond the last matched delimiter.
If n is negative, then the pattern will be applied as many times as possible and the array can have any length.
If n is zero then the pattern will be applied as many times as possible, the array can have any length, and trailing
empty strings will be discarded.
Besides the split() method Strings can also be split using a StringTokenizer.
StringTokenizer is even more restrictive than String.split(), and also a bit harder to use. It is essentially designed for pulling
out tokens delimited by a fixed set of characters (given as a String). Each character will act as a separator. Because of
this restriction, it's about twice as fast as String.split().
Default set of characters are empty spaces (\t\n\r\f). The following example will print out each word separately.
System.out.println(tokenizer.nextToken());
}
the
lazy
fox
jumped
over
the
brown
fence
System.out.println(tokenizer.nextToken());
}
j
mp
ov
r
To have a fine-grained control over joining, you may use StringJoiner class:
sj.add("foo");
sj.add("bar");
sj.add("foobar");
String s1 = "a";
String s2 = "b";
String s3 = "c";
String s = s1 + s2 + s3; // abc
Normally a compiler implementation will perform the above concatenation using methods involving a
StringBuilder under the hood. When compiled, the code would look similar to the below:
StringBuilder has several overloaded methods for appending different types, for example, to append an int instead of
a String. For example, an implementation can convert:
String s1 = "a";
String s2 = "b";
String s = s1 + s2 + 2; // ab2
to the following:
The above examples illustrate a simple concatenation operation that is effectively done in a single place in the code. The
concatenation involves a single instance of the StringBuilder. In some cases, a concatenation is carried out in a cumulative
way such as in a loop:
In such cases, the compiler optimization is usually not applied, and each iteration will create a new StringBuilder object.
This can be optimized by explicitly transforming the code to use a single StringBuilder:
A StringBuilder will be initialized with an empty space of only 16 characters. If you know in advance that you will be
building larger strings, it can be beneficial to initialize it with sufficient size in advance, so that the internal buffer does not
need to be resized:
If (and only if) multiple threads are writing to the same buffer, use StringBuffer, which is a synchronized version of
StringBuilder. But because usually only a single thread writes to a buffer, it is usually faster to use StringBuilder without
synchronization.
This returns a new string that is string1 with string2 added to it at the end. You can also use the concat() method with
string literals, as in:
String b = s.substring(5, 10); // b will hold the string starting at character 5 and ending right before character 10 ("is an")
String b = s.substring(5, b.length()-3); // b will hold the string starting at character 5 ending right before b' s lenght is out of 3 ("is
an exam")
Substrings may also be applied to slice and add/replace character into its original String. For instance, you faced a
Chinese date containing Chinese characters but you want to store it as a well format Date String.
The substring method extracts a piece of a String. When provided one parameter, the parameter is the start and
In JDK <7u6 versions the substring method instantiates a String that shares the same backing char[] as the original String
and has the internal offset and count fields set to the result start and length. Such sharing may cause memory leaks, that
can be prevented by calling new String(s.substring(...)) to force creation of a copy, after which the char[] can be garbage
collected.
Version ≥ Java SE 7
From JDK 7u6 the substring method always copies the entire underlying char[] array, making the complexity linear
compared to the previous constant one but guaranteeing the absence of memory leaks at the same time.
System.getProperty("line.separator")
Version ≥ Java SE 7
Because the new line separator is so commonly needed, from Java 7 on a shortcut method returning exactly the
same result as the code above is available:
System.lineSeparator()
Note: Since it is very unlikely that the new line separator changes during the program's execution, it is a good idea to
store it in in a static final variable instead of retrieving it from the system property every time it is needed.
When using String.format, use %n rather than \n or '\r\n' to output a platform independent new line separator.
1. StringBuilder/StringBuffer:
System.out.println(code);
2. Char array:
// print reversed
System.out.println(new String(array));
String name;
int age;
and later in your code you use the following statement in order to print the object:
System.out.println(person.toString());
Person@7ab89d
This is the result of the implementation of the toString() method defined in the Object class, a superclass of
Person. The documentation of Object.toString() states:
The toString method for class Object returns a string consisting of the name of the class of which the object is
an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the
object. In other words, this method returns a string equal to the value of:
So, for meaningful output, you'll have to override the toString() method:
@Override
System.out.println(person);
If you trim a String that doesn't have any whitespace to remove, you will be returned the same String instance.
Note that the trim() method has its own notion of whitespace, which differs from the notion used by the
Character.isWhitespace() method:
All ASCII control characters with codes U+0000 to U+0020 are considered whitespace and are removed by trim().
This includes U+0020 'SPACE', U+0009 'CHARACTER TABULATION', U+000A 'LINE FEED' and U+000D 'CARRIAGE
RETURN' characters, but also the characters like U+0007 'BELL'.
Unicode whitespace like U+00A0 'NO-BREAK SPACE' or U+2003 'EM SPACE' are not recognized by trim().
switch itself can not be parameterised to be case insensitive, but if absolutely required, can behave insensitive to the
input string by using toLowerCase() or toUpperCase:
switch (myString.toLowerCase()) {
case "case1" :
...
break;
case "case2" :
...
break;
}
Beware
Note: the original String object will be unchanged, the return value holds the changed String.
Exact match
Replace single character with another single character:
String replace(char oldChar, char newChar)
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.
String s = "popcorn";
System.out.println(s.replace('p','W'));
Result:
WoWcorn
Replace sequence of characters with another sequence of characters:
String replace(CharSequence target, CharSequence replacement)
Replaces each substring of this string that matches the literal target sequence with the specified literal
replacement sequence.
Result:
Regex
Note: the grouping uses the $ character to reference the groups, like $1.
Replaces each substring of this string that matches the given regular expression with the given
replacement.
Result:
Replaces the first substring of this string that matches the given regular expression with the given
replacement
Result:
A char in a String is UTF-16 value. Unicode codepoints whose values are ≥ 0x1000 (for example, most emojis) use two
char positions. To count the number of Unicode codepoints in a String, regardless of whether each codepoint fits in a
UTF-16 char value, you can use the codePointCount method:
System.out.println(str.charAt(0)); // "M"
System.out.println(str.charAt(1)); // "y"
System.out.println(str.charAt(2)); // " "
System.out.println(str.charAt(str.length-1)); // Last character "g"
To get the nth character in a string, simply call charAt(n) on a String, where n is the index of the character you would
like to retrieve
import org.apache.commons.lang3.StringUtils;
String text = "One fish, two fish, red fish, blue fish";
Otherwise for does the same with standard Java API's you could use Regular Expressions:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
String text = "One fish, two fish, red fish, blue fish";
System.out.println(countStringInString("fish", text)); // prints 4
System.out.println(countStringInString(",", text)); // prints 3
int stringOccurrences = 0;
while (matcher.find()) {
stringOccurrences++;
}
return stringOccurrences;
}
Methods:
class Test {
public static void main(String args[])
{
String str = "study";
str.concat("tonight");
System.out.println(str); // Output: study
The StringBuffer class has been present since Java 1.0, and provides a variety of methods for building and
modifying a "buffer" containing a sequence of characters.
The StringBuilder class was added in Java 5 to address performance issues with the original StringBuffer class. The
APIs for the two clases are essentially the same. The main difference between StringBuffer and StringBuilder is that
the former is thread-safe and synchronized and the latter is not.
int one = 1;
String color = "red";
StringBuilder sb = new StringBuilder();
sb.append("One=").append(one).append(", Color=").append(color).append('\n'); System.out.print(sb);
(The StringBuffer class is used the same way: just change StringBuilder to StringBuffer in the above)
The StringBuffer and StringBuilder classes are suitable for both assembling and modifying strings; i.e they provide
methods for replacing and removing characters as well as adding them in various. The remining two classes are
specific to the task of assembling strings.
The Formatter class was added in Java 5, and is loosely modeled on the sprintf function in the C standard library.
It takes a format string with embedded format specifiers and a sequences of other arguments, and generates a
string by converting the arguments into text and substituting them in place of the format specifiers. The details of
the format specifiers say how the arguments are converted into text.
The StringJoiner class was added in Java 8. It is a special purpose formatter that succinctly formats a sequence of
strings with separators between them. It is designed with a fluent API, and can be used with Java 8 streams.
This does the same thing as the StringBuilder example above int one = 1;
This creates n new string instances containing 1 to n repetitions of s resulting in a runtime of O(s.length() * n²) = O(s.length() *
(1+2+...+(n-1)+n)).
To avoid this StringBuilder should be used, which allows creating the String in O(s.length() * n) instead:
The set of delimiters (the characters that separate tokens) may be specified either at creation time or on a per-token
basis.
Output:
apple
ball
cat
dog
Output:
apple
ball cat
dog
The regex matches 8 characters after the end of the last match. Since in this case the match is zero-width, we could
more simply say "8 characters after the last match".
Conveniently, \G is initialized to start of input, so it works for the first part of the input too.
int length = 5;
String[] parts = str.split("(?<=\\G.{" + length + "})");
java.sql.Date is a wrapper around millisecond value and is used by JDBC to identify an SQL DATE type
In the below example, we use the java.util.Date() constructor, that creates a Date object and initializes it to represent time
to the nearest millisecond. This date is used in the convert(java.util.Date utilDate) method to return a java.sql.Date object
Example
Output
java.util.Date has both date and time information, whereas java.sql.Date only has date information
2016/04/19 11:45.36
// print it
System.out.println(formattedDate);
Creates a LocalDate
Creates a LocalDateTime
// LocalDate to Date
Date.from(localDate.atStartOfDay(defaultZoneId).toInstant());
// Date to LocalDateTime
LocalDateTime localDateTime = date.toInstant().atZone(defaultZoneId).toLocalDateTime();
// LocalDateTime to Date
Date out = Date.from(localDateTime.atZone(defaultZoneId).toInstant());
To create a new date, you will need a Calendar instance. From there you can set the Calendar instance to the date that
you need.
Calendar c = Calendar.getInstance();
This returns a new Calendar instance set to the current time. Calendar has many methods for mutating it's date and
time or setting it outright. In this case, we'll set it to a specific date.
c.set(1974, 6, 2, 8, 0, 0);
Date d = c.getTime();
The getTime method returns the Date instance that we need. Keep in mind that the Calendar set methods only set one or
more fields, they do not set them all. That is, if you set the year, the other fields remain unchanged.
PITFALL
In many cases, this code snippet fulfills its purpose, but keep in mind that two important parts of the date/time are not
defined.
the (1974, 6, 2, 8, 0, 0) parameters are interpreted within the default timezone, defined somewhere else,
the milliseconds are not set to zero, but filled from the system clock at the time the Calendar instance is
created.
dateFormat.applyPattern("dd-MM-yyyy");
System.out.println(dateFormat.format(today)); //25-02-2016
Note: Here mm (small letter m) denotes minutes and MM (capital M) denotes month. Pay careful attention when
formatting years: capital "Y" (Y) indicates the "week in the year" while lower-case "y" (y) indicates the year.
LocalTime also has a built in toString method that displays the format very nicely.
System.out.println(time);
you can also get, add and subtract hours, minutes, seconds, and nanoseconds from the LocalTime object i.e.
time.plusMinutes(1);
time.getMinutes();
time.minusMinutes(1);
You can turn it into a Date object with the following code:
this class works very nicely within a timer class to simulate an alarm clock.
/**
Parses the date using the given format.
date = objDf.parse(formattedDate);
} catch (ParseException e) {
Do what ever needs to be done with exception.
}
return date;
}
Here this Date object contains the current date and time when this object was created.
Date objects are best created through a Calendar instance since the use of the data constructors is deprecated and
discouraged. To do se we need to get an instance of the Calendar class from the factory method. Then we can set year,
month and day of month by using numbers or in case of months constants provided py the Calendar class to improve
readability and reduce errors.
Along with date, we can also pass time in the order of hour, minutes and seconds.
//Before example
System.out.printf("Is %1$tF before %2$tF? %3$b%n", today, birthdate,
Boolean.valueOf(today.before(birthdate)));
System.out.printf("Is %1$tF before %1$tF? %3$b%n", today, today,
Boolean.valueOf(today.before(today)));
System.out.printf("Is %2$tF before %1$tF? %3$b%n", today, birthdate,
Boolean.valueOf(birthdate.before(today)));
//After example
System.out.printf("Is %1$tF after %2$tF? %3$b%n", today, birthdate,
//Compare example
System.out.printf("Compare %1$tF to %2$tF: %3$d%n", today, birthdate,
Integer.valueOf(today.compareTo(birthdate)));
System.out.printf("Compare %1$tF to %1$tF: %3$d%n", today, birthdate,
Integer.valueOf(today.compareTo(today)));
System.out.printf("Compare %2$tF to %1$tF: %3$d%n", today, birthdate,
Integer.valueOf(birthdate.compareTo(today)));
//Equal example
System.out.printf("Is %1$tF equal to %2$tF? %3$b%n", today, birthdate,
Boolean.valueOf(today.equals(birthdate)));
System.out.printf("Is %1$tF equal to %2$tF? %3$b%n", birthdate, samebirthdate,
Boolean.valueOf(birthdate.equals(samebirthdate)));
System.out.printf(
"Because birthdate.getTime() -> %1$d is different from samebirthdate.getTime() -> %2$d, there are
millisecondes!%n",
Long.valueOf(birthdate.getTime()), Long.valueOf(samebirthdate.getTime()));
System.out.printf("Is %1$tF equal to %2$tF after clearing ms? %3$b%n", birthdate, samebirthdate,
Boolean.valueOf(birthdate.equals(samebirthdate)));
Version ≥ Java SE 8
isBefore, isAfter, compareTo and equals methods
//Use of LocalDate
final LocalDate now = LocalDate.now();
final LocalDate birthdate2 = LocalDate.of(2012, 6, 30); final LocalDate
birthdate3 = LocalDate.of(2012, 6, 30);
//Hours, minutes, second and nanoOfsecond can also be configured with an other class LocalDateTime //LocalDateTime.of(year,
month, dayOfMonth, hour, minute, second, nanoOfSecond);
//isBefore example
System.out.printf("Is %1$tF before %2$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(now.isBefore(birthdate2)));
System.out.printf("Is %1$tF before %1$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(now.isBefore(now)));
System.out.printf("Is %2$tF before %1$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(birthdate2.isBefore(now)));
//isAfter example
System.out.printf("Is %1$tF after %2$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(now.isAfter(birthdate2)));
System.out.printf("Is %1$tF after %1$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(now.isAfter(now)));
System.out.printf("Is %2$tF after %1$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(birthdate2.isAfter(now)));
//compareTo example
System.out.printf("Compare %1$tF to %2$tF %3$d%n", now, birthdate2,
Integer.valueOf(now.compareTo(birthdate2)));
//equals example
System.out.printf("Is %1$tF equal to %2$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(now.equals(birthdate2)));
System.out.printf("Is %1$tF to %2$tF? %3$b%n", birthdate2, birthdate3,
Boolean.valueOf(birthdate2.equals(birthdate3)));
//isEqual example
System.out.printf("Is %1$tF equal to %2$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(now.isEqual(birthdate2)));
System.out.printf("Is %1$tF to %2$tF? %3$b%n", birthdate2, birthdate3,
Boolean.valueOf(birthdate2.isEqual(birthdate3)));
Date comparison before Java 8
Before Java 8, dates could be compared using java.util.Calendar and java.util.Date classes. Date class offers 4
methods to compare dates :
after(Date when)
before(Date when)
compareTo(Date anotherDate)
equals(Object obj)
after, before, compareTo and equals methods compare the values returned by getTime() method for each date.
Value greater than 0 : when the Date is after the Date argument
Value greater than 0 : when the Date is before the Date argument
Value equals to 0 : when the Date is equal to the Date argument
equals results can be surprising as shown in the example because values, like milliseconds, are not initialize with the
same value if not explicitly given.
Since Java 8
With Java 8 a new Object to work with Date is available java.time.LocalDate. LocalDate implements ChronoLocalDate,
the abstract representation of a date where the Chronology, or calendar system, is pluggable.
To have the date time precision the Object java.time.LocalDateTime has to be used. LocalDate and LocalDateTime use
the same methods name for comparing.
Comparing dates using a LocalDate is different from using ChronoLocalDate because the chronology, or calendar system
are not taken in account the first one.
Because most application should use LocalDate, ChronoLocalDate is not included in examples. Further reading here.
Most applications should declare method signatures, fields and variables as LocalDate, not
this[ChronoLocalDate] interface.
In case of LocalDate parameter, isAfter, isBefore, isEqual, equals and compareTo now use this method:
equals method check if the parameter reference equals the date first whereas isEqual directly calls compareTo0.
In case of an other class instance of ChronoLocalDate the dates are compared using the Epoch Day. The Epoch Day count
is a simple incrementing count of days where day 0 is 1970-01-01 (ISO).
System.out.println(date.getYear()); // 116
There are 4 different styles for the text format, SHORT, MEDIUM (this is the default), LONG and FULL, all of which
depend on the locale. If no locale is specified, the system default locale is used.
However, it is possible to display the date represented by the point in time described by the Date object in a
different time zone using e.g. java.text.SimpleDateFormat:
Output:
now, since the method between of the ChronoUnit enumerator takes 2 Temporals as parameters so you can pass without
a problem the LocalDate instances
Date and time with offset information (i.e. no DST changes taken into account)
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.TimeZone;
public class SomeMethodsExamples {
/**
Has the methods of the class {@link LocalDateTime}
*/
public static void checkLocalDateTime() { LocalDateTime
localDateTime = LocalDateTime.now();
System.out.println("Local Date time using static now() method ::: >>> "
localDateTime);
System.out
.println("Following is a static map in ZoneId class which has mapping of short timezone names to their Actual
timezone names");
System.out.println(ZoneId.SHORT_IDS);
/**
This has the methods of the class {@link LocalDate}
*/
public static void checkLocalDate() {
LocalDate localDate = LocalDate.now();
System.out.println("Gives date without Time using now() method. >> "
localDate);
LocalDate localDate2 = LocalDate.now(ZoneId.of(ZoneId.SHORT_IDS
.get("ECT")));
System.out
.println("now() is overridden to take ZoneID as parametere using this we can get the same date under different
timezones. >> "
localDate2);
}
/**
/**
This has the {@link Instant} class methods.
*/
public static void checkInstant() {
Instant instant = Instant.now();
/**
This class checks the methods of the {@link Duration} class.
*/
public static void checkDuration() {
toString() converts the duration to PTnHnMnS format according to ISO
8601 standard. If a field is zero its ignored.
System.out.println(Duration.ofDays(2));
}
/**
Shows Local time without date. It doesn't store or represenet a date and
time. Instead its a representation of Time like clock on the wall.
*/
public static void checkLocalTime() {
LocalTime localTime = LocalTime.now();
System.out.println("LocalTime :: " + localTime);
}
/**
}
}
In formatting and parsing first you pass a String object to DateTimeFormatter, and in turn use it for formatting or parsing.
import java.time.*;
import java.time.format.*;
class DateTimeFormat
{
public static void main(String[] args) {
//Parsing
String pattern = "d-MM-yyyy HH:mm";
DateTimeFormatter dtF1 = DateTimeFormatter.ofPattern(pattern);
//Formatting
DateTimeFormatter dtF2 = DateTimeFormatter.ofPattern("EEE d, MMMM, yyyy HH:mm");
System.out.println(ldtf1.format(dtF2) +"\n"+ldtf1.format(dtF3));
}
}
An important notice, instead of using Custom patterns, it is good practice to use predefined formatters. Your code look
more clear and usage of ISO8061 will definitely help you in the long run.
LocalDate.now()
LocalDate t = LocalDate.now().plusDays(1);
In addition to the plus and minus methods, there are a set of "with" methods that can be used to set a particular field on
a LocalDate instance.
LocalDate.now().withMonth(6);
The example above returns a new instance with the month set to June (this differs from java.util.Date where setMonth
was indexed a 0 making June 5).
Because LocalDate manipulations return immutable LocalDate instances, these methods may also be chained
together.
LocalDate ld = LocalDate.now().plusDays(1).plusYears(1);
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
This class does not store or represent a date or time-zone. Instead, it is a description of the local time as seen on a wall
clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone. This
is a value based class, equals method should be used for comparisons.
Fields
You can also add/subtract hours, minutes or seconds from any object of LocalTime.
now.plusHours(1L);
now1.minusMinutes(20L);
}
}
Commonly you should not use the equals method since it considers two BigDecimals equal only if they are equal in value
and also scale:
import java.math.BigDecimal;
For a starting balance of 10000.00, after 1000 operations for 1.99, we expect the balance to be 8010.00. Using the float
type gives us an answer around 8009.77, which is unacceptably imprecise in the case of monetary calculations. Using
BigDecimal gives us the proper result.
BigDecimal a = BigDecimal.valueOf(20L); //Does not return cached Object reference BigDecimal b = new
BigDecimal(20L); //Does not return cached Object reference
BigDecimal a = BigDecimal.valueOf(15.15); //Preferred way to convert a double (or float) into a BigDecimal, as the value returned is
equal to that resulting from constructing a BigDecimal from the result of using Double.toString(double)
1.Addition
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a + b
BigDecimal result = a.add(b);
System.out.println(result);
Result : 12
2.Subtraction
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a - b
BigDecimal result = a.subtract(b);
System.out.println(result);
Result : -2
When multiplying two BigDecimals the result is going to have scale equal to the sum of the scales of operands.
//Equivalent to result = a * b
BigDecimal result = a.multiply(b);
System.out.println(result);
Result : 36.89931
To change the scale of the result use the overloaded multiply method which allows passing MathContext - an object
describing the rules for operators, in particular the precision and rounding mode of the result. For more information about
available rounding modes please refer to the Oracle Documentation.
//Equivalent to result = a * b
BigDecimal result = a.multiply(b, returnRules);
System.out.println(result);
Result : 36.90
4.Division
Division is a bit more complicated than the other arithmetic operations, for instance consider the below example:
We would expect this to give something similar to : 0.7142857142857143, but we would get:
This would work perfectly well when the result would be a terminating decimal say if I wanted to divide 5 by 2, but for
those numbers which upon dividing would give a non terminating result we would get an ArithmeticException. In the real
world scenario, one cannot predict the values that would be encountered during the division, so we need to specify the
Scale and the Rounding Mode for BigDecimal division. For more information on the Scale and Rounding Mode, refer the
Oracle Documentation.
//Equivalent to result = a / b (Upto 10 Decimal places and Round HALF_UP) BigDecimal result =
a.divide(b,10,RoundingMode.HALF_UP); System.out.println(result);
Result : 0.7142857143
5.Remainder or Modulus
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a % b
BigDecimal result = a.remainder(b);
System.out.println(result);
Result : 5
6.Power
BigDecimal a = new BigDecimal("5");
Result : 9765625
7.Max
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
Result : 7
8.Min
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
Result : 5
//Moves the decimal point to 2 places left of current position BigDecimal result =
a.movePointLeft(2); System.out.println(result);
Result : 52.3449843776
//Moves the decimal point to 3 places right of current position BigDecimal result =
a.movePointRight(3); System.out.println(result);
Result : 5234498.43776
There are many more options and combination of parameters for the above mentioned examples (For instance, there
are 6 variations of the divide method), this set is a non-exhaustive list and covers a few basic examples.
BigDecimal.ZERO
BigDecimal.ONE
BigDecimal.TEN
By using the static properties, you avoid an unnecessary instantiation, also you've got a literal in your code instead of a
'magic number'.
//Bad example:
BigDecimal bad0 = new BigDecimal(0);
BigDecimal bad1 = new BigDecimal(1);
BigDecimal bad10 = new BigDecimal(10);
//Good Example:
BigDecimal good0 = BigDecimal.ZERO;
BigDecimal good1 = BigDecimal.ONE;
BigDecimal good10 = BigDecimal.TEN;
integers:
which will widen the intValue integer to long, using sign bit extension for negative values, so that negative values will
stay negative.
Following constructor is used to translate the String representation of a BigInteger in the specified radix into a
BigInteger.
Java also supports direct conversion of bytes to an instance of BigInteger. Currently only signed and unsigned big endian
encoding may be used:
This will generate a BigInteger instance with value -128 as the first bit is interpreted as the sign bit.
This will generate a BigInteger instance with value 128 as the bytes are interpreted as unsigned number, and the sign is
explicitly set to 1, a positive number.
There's also BigInteger.TWO (value of "2"), but you can't use it in your code because it's private.
Addition: 10 + 10 = 20
output: 20
Subtraction: 10 - 9 = 1
output: 1
Division: 10 / 5 = 2
output: 2
Division: 17/4 = 4
output: 4
output: 50
Power: 10 ^ 3 = 1000
output: 1000
Remainder: 10 % 6 = 4
output: 4
System.out.println(value1.gcd(value2));
Output: 6
System.out.println(value1.max(value2));
Output: 11
System.out.println(value1.min(value2));
Output: 10
For example:
if(one.equals(two)){
System.out.println("Equal");
}
else{
System.out.println("Not Equal");
}
Output:
Not Equal
Note:
== operator: compares references; i.e. whether two values refer to the same object
equals() method: compares the content of two BigIntegers.
if (firstBigInteger == secondBigInteger) {
// Only checks for reference equality, not content equality!
}
Doing so may lead to unexpected behavior, as the == operator only checks for reference equality. If both
BigIntegers contain the same content, but do not refer to the same object, this will fail. Instead, compare
BigIntegers using the equals methods, as explained above.
You can also compare your BigInteger to constant values like 0,1,10.
for example:
You can also compare two BigIntegers by using compareTo() method, as following: compareTo() returns 3 values.
if(reallyBig.compareTo(reallyBig1) == 0){
//code when both are equal.
}
else if(reallyBig.compareTo(reallyBig1) == 1){ //code when reallyBig is
greater than reallyBig1.
}
else if(reallyBig.compareTo(reallyBig1) == -1){
//code when reallyBig is less than reallyBig1.
}
Binary Or:
val1.or(val2);
Binary And:
val1.and(val2);
Binary Xor:
val1.xor(val2);
RightShift:
LeftShift:
val1.not();
Output: 5
NAND (And-Not):*
val1.andNot(val2);
Output: 7
then you'll end up with a BigInteger whose value is between 0 (inclusive) and 2bitCount (exclusive).
This also means that new BigInteger(2147483647, sourceOfRandomness) may return all positive BigIntegers given
enough time.
What will the sourceOfRandomness be is up to you. For example, a new Random() is good enough in most cases:
If you're willing to give up speed for higher-quality random numbers, you can use a new
="https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html" rel="nofollow
noreferrer">SecureRandom() instead:
You can even implement an algorithm on-the-fly with an anonymous class! Note that rolling out your own RNG
algorithm will end you up with low quality randomness, so always be sure to use an algorithm that is proven to be
decent unless you want the resulting BigInteger(s) to be predictable.
@Override
protected int next(int bits) {
seed = ((22695477 * seed) + 1) & 2147483647; // Values shamelessly stolen from
="https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use" rel="nofollow
noreferrer">Wikipedia return seed; } });
Format Number
numberFormat.format(10000000.99);
Format Currency
Format Percentage
numberFormat.setMinimumIntegerDigits(int digits)
numberFormat.setMaximumIntegerDigits(int digits)
numberFormat.setMinimumFractionDigits(int digits)
numberFormat.setMaximumFractionDigits(int digits)
Prints
FIRST_BIT: true
SECOND_BIT: false
THIRD_BIT: true
FOURTh_BIT: false
FIFTH_BIT: true
BIT_55: true
which matches that mask we passed as checkBitMask parameter: FIRST_BIT | THIRD_BIT | FIFTH_BIT | BIT_55.
final BitSet bitSet = new BitSet(8); // by default all bits are unset
bitSet.flip(6); // {0, 2, 4}
BitSet implements Clonable and Serializable, and under the hood all bit values are stored in long[] words field, that expands
automatically.
bitSet.and(new BitSet(8));
bitSet.or(new BitSet(8));
bitSet.xor(new BitSet(8));
bitSet.andNot(new BitSet(8));
boolean isPowerOfTwo(int x)
{
return (x != 0) && ((x & (x - 1)) == 0);
}
Let’s suppose, we have three kind of permissions, READ, WRITE and EXECUTE. Each permission can range from 0 to
7. (Let’s assume 4 bit number system)
How can we get the (12 bit number) permissions, set on above (12 bit number)?
So, this is how we can get the EXECUTE permissions of the RESOURCE. Now, what if we want to get READ
permissions of the RESOURCE?
Right? You are probably assuming this? But, permissions are resulted in 1024. We want to get only READ permissions
for the resource. Don’t worry, that’s why we had the shift operators. If we see, READ permissions are 8 bits behind the
actual result, so if apply some shift operator, which will bring READ permissions to the very right of the result? What if we
do:
0100 0000 0000 >> 8 => 0000 0000 0100 (Because it’s a positive number so replaced with 0’s, if you don’t
care about sign, just use unsigned right shift operator)
Now, for example, we are given READ, WRITE, EXECUTE permissions for a RESOURCE, what can we do to make
permissions for this RESOURCE?
Let’s first take the example of binary permissions. (Still assuming 4 bit number system)
READ = 0001
WRITE = 0100
EXECUTE = 0110
READ | WRITE | EXECUTE, you are somewhat right but not exactly. See, what will happen if we will perform READ |
WRITE | EXECUTE
But permissions are actually being represented (in our example) as 0001 0100 0110
So, in order to do this, we know that READ is placed 8 bits behind, WRITE is placed 4 bits behind and PERMISSIONS is
placed at the last. The number system being used for RESOURCE permissions is actually 12 bit (in our example). It
can(will) be different in different systems.
Basic shift operators >> and << are signed operators. They will conserve the sign of the value.
But it is common for programmers to use numbers to store unsigned values. For an int, it means shifting the range to
[0, 2^32 - 1], to have twice as much value as with a signed int.
For those power users, the bit for sign as no meaning. That's why Java added >>>, a left-shift operator, disregarding that
sign bit.
This comes from the intended definition of right-shift. As it fills the emptied places on the left, there are no decision to
take regarding the bit of sign. As a consequence, there is no need for 2 different operators.
Examples:
This is especially useful when defining constant values that should make it apparent, that a power of 2 is used,
For example, one can pack 3 bytes - such as color code in RGB - into an single int.
Arrays allow for the storage and retrieval of an arbitrary quantity of values. They are analogous to vectors in
mathematics. Arrays of arrays are analogous to matrices, and act as multidimensional arrays. Arrays can store any data
of any type: primitives such as int or reference types such as Object.
float[] boats = new float[5]; // Array of five 32-bit floating point numbers. double[] header = new double[] { 4.56,
332.267, 7.0, 0.3367, 10.0 };
Array of five 64-bit floating point numbers.
String[] theory = new String[] { "a", "b", "c" };
Array of three strings (reference type).
Object[] dArt = new Object[] { new Object(), "We love Stack Overflow.", new Integer(3) }; // Array of three Objects
(reference type).
For the last example, note that subtypes of the declared array type are allowed in the array.
Arrays for user defined types can also be built similar to primitive types
Intro
Each item in an array is called an element, and each element is accessed by its numerical index. The length of an
array is established when the array is created:
The size of an array is fixed at runtime when initialized. It cannot be changed after initialization. If the size must be
mutable at runtime, a Collection class such as ArrayList should be used instead. ArrayList stores elements in an array and
supports resizing by allocating a new array and copying elements from the old array.
the values are stored in the array itself. In the absence of an initializer (as in array2 above), the default value
assigned to each element is 0 (zero).
then the array contains references to objects of type SomeClassOrInterface. Those references can refer to an instance of
SomeClassOrInterface or any subclass (for classes) or implementing class (for interfaces) of SomeClassOrInterface. If the
array declaration has no initializer then the default value of null is assigned to each element.
Because all arrays are int-indexed, the size of an array must be specified by an int. The size of the array cannot be
specified as a long:
Arrays use a zero-based index system, which means indexing starts at 0 and ends at length - 1.
For example, the following image represents an array with size 10. Here, the first element is at index 0 and the last
element is at index 9, instead of the first element being at index 1 and the last element at index 10 (see figure below).
Accesses to elements of arrays are done in constant time. That means accessing to the first element of the array has
the same cost (in time) of accessing the second element, the third element and so on.
Java offers several ways of defining and initializing arrays, including literal and constructor notations. When
0 for primitive numerical types: byte, short, int, long, float, and double.
'\u0000' (null character) for the char type.
false for the boolean type.
null for reference types.
When declaring an array, [] will appear as part of the type at the beginning of the declaration (after the type name), or as
part of the declarator for a particular variable (after variable name), or both:
In the following example, both declarations are correct and can compile and run without any problems. However, both
the Java Coding Convention and the Google Java Style Guide discourage the form with brackets after the variable
name—the brackets identify the array type and should appear with the type designation. The same should be used for
method return signatures.
float array[]; /* and */ int foo()[] { ... } /* are discouraged */ float[] array; /* and */ int[]
foo() { ... } /* are encouraged */
The discouraged type is meant to accommodate transitioning C users, who are familiar with the syntax for C which has
the brackets after the variable name.
However, since it's an empty array, no elements can be read from it or assigned to it:
Such empty arrays are typically useful as return values, so that the calling code only has to worry about dealing with an
array, rather than a potential null value that may lead to a NullPointerException.
Note: array.length returns the actual size of the array and not the number of array elements which were assigned a value,
unlike ArrayList.size() which returns the number of array elements which were assigned a value.
It will create two three-length int arrays—a[0] and a[1]. This is very similar to the classical, C-style initialization of
rectangular multi-dimensional arrays.
Unlike C, where only rectangular multi-dimensional arrays are supported, inner arrays do not need to be of the same
length, or even defined:
Here, a[0] is a one-length int array, whereas a[1] is a two-length int array and a[2] is null. Arrays like this are called
jagged arrays or ragged arrays, that is, they are arrays of arrays. Multi-dimensional arrays in Java are implemented as
arrays of arrays, i.e. array[i][j][k] is equivalent to ((array[i])[j])[k]. Unlike C#, the syntax array[i,j] is not supported in Java.
Live on Ideone
In addition to the String literals and primitives shown above, the shortcut syntax for array initialization also works with
canonical Object types:
Because arrays are covariant, a reference type array can be initialized as an array of a subclass, although an
ArrayStoreException will be thrown if you try to set an element to something other than a String:
The shortcut syntax cannot be used for this because the shortcut syntax would have an implicit type of Object[].
An array can be initialized with zero elements by using String[] emptyArray = new String[0]. For example, an array with
zero length like this is used for Creating an Array from a Collection when the method needs the runtime type of an
object.
In both primitive and reference types, an empty array initialization (for example String[] array8 = new String[3])
will initialize the array with the default value for each data type.
In generic classes, arrays of generic types cannot be initialized like this due to type erasure:
public MyGenericClass() {
a = new T[5]; // Compile time error: generic array creation
}
}
Instead, they can be created using one of the following methods: (note that these will generate unchecked
warnings)
This is the simplest method, but since the underlying array is still of type Object[], this method does not provide
type safety. Therefore, this method of creating an array is best used only within the generic class - not exposed
publicly.
Here the class of T has to be explicitly passed to the constructor. The return type of Array.newInstance is always
Object. However, this method is safer because the newly created array is always of type T[], and therefore can
be safely externalized.
Arrays.fill() can be used to fill an array with the same value after initialization:
Live on Ideone
fill() can also assign a value to each element of the specified range of the array:
Live on Ideone
Version ≥ Java SE 8
Since Java version 8, the method setAll, and its Concurrent equivalent parallelSetAll, can be used to set every element of
an array to generated values. These methods are passed a generator function which accepts an index and returns the
desired value for that position.
The following example creates an integer array and sets all of its elements to their respective index value:
Live on Ideone
The value of an index for an array element must be a whole number (0, 1, 2, 3, 4, ...) and less than the length of the
array (indexes are zero-based). Otherwise, an ArrayIndexOutOfBoundsException will be thrown:
It is not possible to re-initialize an array via a shortcut syntax with an array initializer since an array initializer can only
be specified in a field declaration or local variable declaration, or as a part of an array creation expression.
However, it is possible to create a new array and assign it to the variable being used to reference the old array. While this
results in the array referenced by that variable being re-initialized, the variable contents are a completely new array. To
do this, the new operator can be used with an array initializer and assigned to the array variable:
array = { 1, 2, 3, 4 }; // Compile-time error! Can't re-initialize an array via shortcut // syntax with array initializer.
Live on Ideone
Note: This list is backed by (a view of) the original array, meaning that any changes to the list will change the array and
vice versa. However, changes to the list that would change its size (and hence the array length) will throw an
exception.
To create a copy of the list, use the constructor of java.util.ArrayList taking a Collection as an argument:
Version ≥ Java SE 5
String[] stringArray = {"foo", "bar", "baz"};
List<String> stringList = new ArrayList<String>(Arrays.asList(stringArray));
Version ≥ Java SE 7
In Java SE 7 and later, a pair of angle brackets <> (empty set of type arguments) can be used, which is called the
Diamond. The compiler can determine the type arguments from the context. This means the type information can be left
out when calling the constructor of ArrayList and it will be inferred automatically during compilation. This is called Type
Inference which is a part of Java Generics.
// Using Arrays.asList()
// Using ArrayList.addAll()
// Using Collections.addAll()
Version ≥ Java SE 8
// Using Streams
This method returns List, which is an instance of Arrays$ArrayList(static inner class of Arrays) and not
java.util.ArrayList. The resulting List is of fixed-size. That means, adding or removing elements is not supported
and will throw an UnsupportedOperationException:
A new List can be created by passing an array-backed List to the constructor of a new List. This creates a new
copy of the data, which has changeable size and that is not backed by the original array:
Calling <T> List<T> asList(T... a) on a primitive array, such as an int[], will produce a List<int[]> whose only
element is the source primitive array instead of the actual elements of the source array.
The reason for this behavior is that primitive types cannot be used in place of generic type parameters, so the
entire primitive array replaces the generic type parameter in this case. In order to convert a primitive array to a
List, first of all, convert the primitive array to an array of the corresponding wrapper type (i.e. call Arrays.asList on
an Integer[] instead of an int[]).
View Demo
Integer[] arr = {1, 2, 3}; // object array of Integer (wrapper for int)
System.out.println(Arrays.asList(arr).contains(1));
View Demo
This will also print true, because the array will be interpreted as an Integer[]):
System.out.println(Arrays.asList(1,2,3).contains(1));
View Demo
Object[] toArray()
Version ≥ Java SE 5
Set<String> set = new HashSet<String>();
set.add("red");
set.add("blue");
although set is a Set<String>, toArray() returns an Object[] not a String[] Object[] objectArray =
set.toArray();
Version ≥ Java SE 5
Set<String> set = new HashSet<String>();
set.add("red");
set.add("blue");
The array does not need to be created up front with the correct size.
Only the array type matters. (If the size is wrong, a new array will
be created with the same type.)
String[] stringArray = set.toArray(new String[0]);
The difference between them is more than just having untyped vs typed results. Their performance can differ as well
(for details please read this performance analysis section):
Object[] toArray() uses vectorized arraycopy, which is much faster than the type-checked arraycopy used in T[]
toArray(T[] a).
T[] toArray(new T[non-zero-size]) needs to zero-out the array at runtime, while T[] toArray(new T[0]) does not. Such
avoidance makes the latter call faster than the former. Detailed analysis here : Arrays of Wisdom of the Ancients.
Version ≥ Java SE 8
Starting from Java SE 8+, where the concept of Stream has been introduced, it is possible to use the Stream
produced by the collection in order to create a new Array using the Stream.toArray method.
Examples taken from two answers (1, 2) to Converting 'ArrayList to 'String[]' in Java on Stack Overflow.
int rows = 3;
int columns = 3;
int[][] table = new int[rows][columns];
The array can be indexed and assign values to it with this construct. Note that the unassigned values are the default
values for the type of an array, in this case 0 for int.
table[0][0] = 0;
table[0][1] = 1;
table[0][2] = 2;
It is also possible to instantiate a dimension at a time, and even make non-rectangular arrays. These are more
commonly referred to as jagged arrays.
It is important to note that although it is possible to define any dimension of jagged array, it's preceding level must be
defined.
// valid
String[][] employeeGraph = new String[30][];
// invalid
int[][] unshapenMatrix = new int[][10];
// also invalid
int[][][] misshapenGrid = new int[100][][10];
Multidimensional arrays and jagged arrays can also be initialized with a literal expression. The following declares and
populates a 2x3 int array:
int[][] table = {
{1, 2, 3},
{4, 5, 6}
};
Note: Jagged subarrays may also be null. For instance, the following code declares and populates a two
dimensional int array whose first subarray is null, second subarray is of zero length, third subarray is of one length
and the last subarray is a two length array:
int[][] table = {
null,
{},
{1},
{1,2}
};
For multidimensional array it is possible to extract arrays of lower-level dimension by their indices:
Arrays are zero-based indexed, so the index of the first element is 0 and the index of the last element is the array
capacity minus 1 (i.e. array.length - 1).
Therefore, any request for an array element by the index i has to satisfy the condition 0 <= i < array.length, otherwise
the ArrayIndexOutOfBoundsException will be thrown.
Output:
Note that the illegal index that is being accessed is also included in the exception ( 2 in the example); this information could
To avoid this, simply check that the index is within the limits of the array:
int index = 2;
if (index >= 0 && index < people.length) {
System.out.println(people[index]);
}
Although Integer[] is a subclass of Number[], it can only hold Integers, and trying to assign a Long element throws a runtime
exception.
Note that this behavior is unique to arrays, and can be avoided by using a generic List instead:
It's not necessary for all of the array elements to share the same type, as long as they are a subclass of the array's
type:
interface I {}
class A implements I {}
class B implements I {}
class C implements I {}
I[] array10 = new I[] { new A(), new B(), new C() }; // Create an array with new
// operator and array initializer.
I[] array11 = { new A(), new B(), new C() }; // Shortcut syntax with array
// initializer.
I[] array13 = new A[] { new A(), new A() }; // Works because A implements I.
Object[] array14 = new Object[] { "Hello, World!", 3.14159, 42 }; // Create an array with // new operator and array initializer.
Converting an array of primitives to Stream using Arrays.stream() will transform the array to a primitive
specialization of Stream:
You can also limit the Stream to a range of elements in the array. The start index is inclusive and the end index is
exclusive:
A method similar to Arrays.stream() appears in the Stream class: Stream.of(). The difference is that Stream.of()
uses a varargs parameter, so you can write something like:
It is worth noting here that there is no direct way to use an Iterator on an Array, but through the Arrays library it can be
easily converted to a list to obtain an Iterable object.
For primitive arrays (using java 8) use streams (specifically in this example - Arrays.stream -> IntStream):
If you can't use streams (no java 8), you can choose to use google's guava library:
In two-dimensional arrays or more, both techniques can be used in a slightly more complex fashion.
Example:
It is impossible to set an Array to any non-uniform value without using an index based loop.
Of course you can also use while or do-while loops when iterating using indices.
One note of caution: when using array indices, make sure the index is between 0 and array.length - 1 (both
inclusive). Don't make hard coded assumptions on the array length otherwise you might break your code if the array
length changes but your hard coded values don't.
Example:
// DON'T DO THIS :
for (int i = 0; i < 4; i++) {
numbers[i] += 1;
}
}
It's also best if you don't use fancy calculations to get the index but use the index to iterate and if you need
different values calculate those.
Example:
// DON'T DO THIS :
int doubleLength = array.length * 2;
for (int i = 0; i < doubleLength; i += 2) {
array[i / 2] = i;
}
}
Iterating over a temporary array instead of repeating code can make your code cleaner. It can be used where the
same operation is performed on multiple variables.
int arms = 5;
copy-paste approach:
System.out.println(name);
System.out.println(eyeCount);
System.out.println(height);
System.out.println(legs);
System.out.println(arms);
Keep in mind that this code should not be used in performance-critical sections, as an array is created every time the
loop is entered, and that primitive variables will be copied into the array and thus cannot be modified.
Since Java 1.5 you can get a String representation of the contents of the specified array without iterating over its every
element. Just use Arrays.toString(Object[]) or Arrays.deepToString(Object[]) for multidimentional arrays:
Arrays.toString() method uses Object.toString() method to produce String values of every item in the array, beside primitive
type array, it can be used for all type of arrays. For instance:
If no overridden toString() exists for the class, then the inherited toString() from Object will be used. Usually the output is
then not very useful, for example:
import java.util.Arrays;
String is not a numeric data, it defines it's own order which is called lexicographic order, also known as alphabetic order.
When you sort an array of String using sort() method, it sorts array into natural order defined by Comparable interface,
as shown below :
Increasing Order
Output:
Decreasing Order
Output:
String array after sorting in descending order : [Steve, Shane, John, Ben, Adam]
In order to sort an object array, all elements must implement either Comparable or Comparator interface to define the
order of the sorting.
We can use either sort(Object[]) method to sort an object array on its natural order, but you must ensure that all elements
in the array must implement Comparable.
Furthermore, they must be mutually comparable as well, for example e1.compareTo(e2) must not throw a
ClassCastException for any elements e1 and e2 in the array. Alternatively you can sort an Object array on custom order
using sort(T[], Comparator) method as shown in following example.
How to Sort Object Array in Java using Comparator and Comparable Course[]
courses = new Course[4];
courses[0] = new Course(101, "Java", 200); courses[1] =
new Course(201, "Ruby", 300); courses[2] = new
Course(301, "Python", 400); courses[3] = new Course(401,
"Scala", 500);
Arrays.sort(courses);
System.out.println("Object array after sorting in natural order : " + Arrays.toString(courses));
Output:
Object array before sorting : [#101 Java@200 , #201 Ruby@300 , #301 Python@400 , #401 Scala@500 ]
Object array after sorting in natural order : [#101 Java@200 , #201 Ruby@300 , #301 Python@400 ,
#401 Scala@500 ]
Object array after sorting by price : [#101 Java@200 , #201 Ruby@300 , #301 Python@400 , #401
Scala@500 ]
Object array after sorting by name : [#101 Java@200 , #301 Python@400 , #201 Ruby@300 , #401
Scala@500 ]
The length field in an array stores the size of an array. It is a final field and cannot be modified.
This code shows the difference between the length of an array and amount of objects an array stores.
Result:
String[] strings = new String[] { "A", "B", "C" }; int[] ints = new int[] {
1, 2, 3, 4 };
In addition, each one sets index or index2 to either the index of required element, or -1 if the element is not present.
Using a Stream
Version ≥ Java SE 8
int index = IntStream.range(0, strings.length)
.filter(i -> "A".equals(strings[i]))
.findFirst()
.orElse(-1); // If not present, gives us -1.
Similar for an array of primitives
Note: Using a direct linear search is more efficient than wrapping in a list.
The examples above can be adapted to test if the array contains an element by simply testing to see if the index
computed is greater or equal to zero.
Suppose (for example) that a new element needs to be added to the listOfCities array defined as above. To do this, you
will need to:
There are various ways to do the above. Prior to Java 6, the most concise way was:
From Java 6 onwards, the Arrays.copyOf and Arrays.copyOfRange methods can do this more simply:
For other ways to copy an array, refer to the following example. Bear in mind that you need an array copy with a
different length to the original when resizing.
Copying arrays
It is inefficient. Making an array bigger (or smaller) involves copying many or all of the existing array
elements, and allocating a new array object. The larger the array, the more expensive it gets.
You need to be able to update any "live" variables that contain references to the old array.
One alternative is to create the array with a large enough size to start with. This is only viable if you can determine that
size accurately before allocating the array. If you cannot do that, then the problem of resizing the array arises again.
The other alternative is to use a data structure class provided by the Java SE class library or a third-party library. For
example, the Java SE "collections" framework provides a number of implementations of the List, Set and Map APIs with
different runtime properties. The ArrayList class is closest to performance characteristics of a plain array (e.g. O(N)
lookup, O(1) get and set, O(N) random insertion and deletion) while providing more efficient resizing without the
reference update problem.
(The resize efficiency for ArrayList comes from its strategy of doubling the size of the backing array on each resize. For a
typical use-case, this means that you only resize occasionally. When you amortize over the lifetime of the list, the resize
cost per insert is O(1). It may be possible to use the same strategy when resizing a plain array.)
To convert the array, it's possible to use streams (in Java 8 and above):
With lower versions it can be by iterating the primitive array and explicitly copying it to the boxed array:
Version ≥ Java SE 8
Integer[] boxedArray = {1, 2, 3, 4};
int[] primitiveArray =
Arrays.stream(boxedArray).mapToInt(Integer::intValue).toArray();
Version < Java SE 8
Using ArrayList
You can convert the array to a java.util.List, remove the element and convert the list back to an array as follows:
Creates a new array with the same size as the list and copies the list
elements to it.
array = list.toArray(new String[list.size()]);
Using System.arraycopy
System.arraycopy() can be used to make a copy of the original array and remove the element you want. Below an
example:
System.out.println(Arrays.toString(result)); //[1, 3, 4]
To easily remove an element, you can use the Apache Commons Lang library and especially the static method
removeElement() of the class ArrayUtils. Below an example:
When the element type is a reference type, Arrays.equals() calls equals() on the array elements to determine equality. In
particular, if the element type is itself an array type, identity comparison will be used. To compare multidimensional
arrays for equality, use Arrays.deepEquals() instead as below:
int a[] = { 1, 2, 3 };
int b[] = { 1, 2, 3 };
Because sets and maps use equals() and hashCode(), arrays are generally not useful as set elements or map keys. Either
wrap them in a helper class that implements equals() and hashCode() in terms of the array elements, or convert them to
List instances and store the lists.
for loop
int[] a = { 4, 1, 3, 2 };
int[] b = new int[a.length];
for (int i = 0; i < a.length; i++) {
b[i] = a[i];
}
Object.clone()
int[] a = { 4, 1, 3, 2 };
int[] b = a.clone(); // [4, 1, 3, 2]
Note that the Object.clone method for an array performs a shallow copy, i.e. it returns a reference to a new array which
references the same elements as the source array.
Arrays.copyOf()
java.util.Arrays provides an easy way to perform the copy of an array to another. Here is the basic usage:
Note that Arrays.copyOf also provides an overload which allows you to change the type of the array:
System.arraycopy()
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
Copies an array from the specified source array, beginning at the specified position, to the specified
position of the destination array.
int[] a = { 4, 1, 3, 2 };
int[] b = new int[a.length];
System.arraycopy(a, 0, b, 0, a.length); // [4, 1, 3, 2]
Arrays.copyOfRange()
Mainly used to copy a part of an Array, you can also use it to copy whole array to another as below:
int[] a = { 4, 1, 3, 2 };
int[] b = Arrays.copyOfRange(a, 0, a.length); // [4, 1, 3, 2]
public static <T, A> T[] castArray(T[] target, A[] array) { for (int i = 0; i <
array.length; i++) {
target[i] = (T) array[i];
Java SE provides the method Arrays.copyOf(original, newLength, newType) for this purpose:
Collections framework contains interfaces for Collection<O>, with main sub-interfaces List<O> and Set<O>, and mapping
collection Map<K,V>. Collections are the root interface and are being implemented by many other collection
frameworks.
Given the following list, here are some examples that will give an unexpected result and some that will give the
correct result.
The code sample will only print Apple and Strawberry. Banana is skipped because it moves to index 0 once Apple is
deleted, but at the same time i gets incremented to 1.
Throws: java.util.ConcurrentModificationException
The Iterator interface has a remove() method built in just for this case. However, this method is marked as
"optional" in the documentation, and it might throw an UnsupportedOperationException.
Therefore, it is advisable to check the documentation to make sure this operation is supported (in practice, unless the
collection is an immutable one obtained through a 3rd party library or the use of one of the Collections.unmodifiable...()
method, the operation is almost always supported).
While using an Iterator a ConcurrentModificationException is thrown when the modCount of the List is changed from when the
Iterator was created. This could have happened in the same thread or in a multi-threaded application sharing the same
list.
A modCount is an int variable which counts the number of times this list has been structurally modified. A structural
change essentially means an add() or remove() operation being invoked on Collection object (changes made by Iterator are
not counted). When the Iterator is created, it stores this modCount and on every iteration of the List checks if the current
modCount is same as and when the Iterator was created. If there is a change in the modCount value it throws a
ConcurrentModificationException.
Hence for the above-declared list, an operation like below will not throw any exception:
System.out.println(fruitIterator.next());
}
But adding a new element to the List after initializing an Iterator will throw a
ConcurrentModificationException:
Iterating backwards
for (int i = (fruits.size() - 1); i >=0; i--) {
System.out.println (fruits.get(i));
if ("Apple".equals(fruits.get(i))) {
fruits.remove(i);
}
}
This does not skip anything. The downside of this approach is that the output is reverse. However, in most cases
where you remove items that will not matter. You should never do this with LinkedList.
This does not skip anything. When the ith element is removed from the List, the element originally positioned at index
i+1 becomes the new ith element. Therefore, the loop can decrement i in order for the next iteration to process the next
element, without skipping.
This solution enables the developer to check if the correct elements are removed in a cleaner way.
Version ≥ Java SE 8
In Java 8 the following alternatives are possible. These are cleaner and more straight forward if the removing does
not have to happen in a loop.
Filtering a Stream
A List can be streamed and filtered. A proper filter can be used to remove all undesired elements.
List<String> filteredList =
fruits.stream().filter(p -> !"Apple".equals(p)).collect(Collectors.toList());
Note that unlike all the other examples here, this example produces a new List instance and keeps the original List
unchanged.
Using removeIf
Saves the overhead of constructing a stream if all that is needed is to remove a set of items.
A simple way to construct a List from individual data values is to use java.utils.Arrays method Arrays.asList:
All standard collection implementations provide constructors that take another collection as an argument adding all
elements to the new collection at the time of construction:
Another great framework is Google Guava that is amazing utility class (providing convenience static methods) for
construction of different types of standard collections Lists and Sets:
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
...
List<String> list1 = Lists.newArrayList("ab", "bc", "cd");
List<String> list2 = Lists.newArrayList(data);
Set<String> set4 = Sets.newHashSet(data);
SortedSet<String> set5 = Sets.newTreeSet("bc", "cd", "ab", "bc", "cd");
Mapping Collections
Java Collections framework
Similarly for maps, given a Map<String, Object> map a new map can be constructed with all elements as follows:
Using Apache Commons you can create Map using array in ArrayUtils.toMap as well as MapUtils.toMap:
import org.apache.commons.lang3.ArrayUtils;
...
Taken from org.apache.commons.lang.ArrayUtils#toMap JavaDoc
Each element of the array must be either a Map.Entry or an Array, containing at least two elements, where the first
element is used as key and the second as value.
import com.google.common.collect.Maps;
...
void howToCreateMapsMethod(Function<? super K,V> valueFunction, Iterable<K>
keys1,
Set<K> keys2,
SortedSet<K> keys3) {
ImmutableMap<K, V> map1 = toMap(keys1, valueFunction); // Immutable copy
Map<K, V> map2 = asMap(keys2, valueFunction); // Live Map view
SortedMap<K, V> map3 = toMap(keys3, valueFunction); // Live Map view
}
Version ≥ Java SE 8
Stream.of("xyz", "abc").collect(Collectors.toList());
or
Arrays.stream("xyz", "abc").collect(Collectors.toList());
aListOfFruits.add("Melon");
aListOfFruits.add("Strawberry");
In the above example, the ArrayList will contain the String "Melon" at index 0 and the String "Strawberry" at index 1.
Also we can add multiple elements with addAll(Collection<? extends E> c) method
Now "Onion" is placed at 0 index in aListOfFruitsAndVeggies, "Melon" is at index 1 and "Strawberry" is at index 2.
names.parallelStream().forEach(System.out::println);
Version ≥ Java SE 5
for (String name : names) {
System.out.println(name);
}
Version < Java SE 5
for (int i = 0; i < names.size(); i++) {
System.out.println(names.get(i));
}
Version ≥ Java SE 1.2
//Iterates list in backward direction once reaches the last element from above iterator in forward direction
while(listIterator.hasPrevious()){
System.out.println(listIterator.previous());
}
Iterating over Set
Set<String> names = new HashSet<>(Arrays.asList("Clementine", "Duran", "Mike"));
Version ≥ Java SE 8
names.forEach(System.out::println);
Version ≥ Java SE 5
for (Iterator<String> iterator = names.iterator(); iterator.hasNext(); ) {
System.out.println(iterator.next());
}
These methods are generic and will automatically convert the returned collection to the type it is assigned to. That is, an
invocation of e.g. emptyList() can be assigned to any type of List and likewise for emptySet() and emptyMap().
The collections returned by these methods are immutable in that they will throw UnsupportedOperationException if you
attempt to call methods which would change their contents ( add, put, etc.). These collections are primarily useful as
substitutes for empty method results or other default values, instead of using null or creating objects with new.
Example:
Output:
Before Sublist [Hello1, Hello2]
After sublist changes [Hello1, Hello3, Hello2]
Set subSet(fromIndex,toIndex)
The returned set will throw an IllegalArgumentException on an attempt to insert an element outside its range.
Map subMap(fromKey,toKey)
If fromKey is greater than toKey or if this map itself has a restricted range, and fromKey or toKey lies outside the
bounds of the range then it throws IllegalArgumentException.
All the collections support backed collections means changes made on the sub collection will have same change on the
main collection.
An unmodifiable collection is often a copy of a modifiable collection which guarantees that the collection itself
cannot be altered. Attempts to modify it will result in an UnsupportedOperationException exception.
It is important to notice that objects which are present inside the collection can still be altered.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.List;
If we run this code, ConcurrentModificationException will be raised since the code modifies the collection while
iterating it. The same exception may occur if one of the multiple threads working with the same list is trying to modify the
collection while others iterate over it. Concurrent modification of collections in multiple threads is a natural thing, but
should be treated with usual tools from the concurrent programming toolbox such as synchronization locks, special
collections adopted for concurrent modification, modifying the cloned collection from initial etc.
Note: This is only adding on to the Removing items from a List within a loop example:
The following method takes in two Collection objects and performs the magic of removing the elements in our
removeNameList that match with elements in nameList.
Calling the method and passing in the nameList and the removeNameListas follows
removeNames(nameList,removeNameList);
Will produce the following output:
Array List before removing names: James Smith Sonny Huckle Berry Finn Allan
Array List after removing names: James Smith Finn Allan
A simple neat use for Collections that may come in handy to remove repeating elements within lists.
ListUtils.union(listOne,listTwo);
Version ≥ Java SE 8
The stuff we want to iterate upon has to be Iterable and expose iterator().
Design a java.util.Iterator by overriding hasNext(), next() and remove().
package org.algorithms.linkedlist;
import java.util.Iterator;
import java.util.NoSuchElementException;
Node(T data) {
this.data = data;
}
}
@Override
public boolean hasNext() {
return node != null;
}
@Override
public T next() {
if (!hasNext())
throw new NoSuchElementException();
Node<T> prevNode = node;
node = node.next;
return prevNode.data;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Removal logic not implemented.");
}
}
class App {
public static void main(String[] args) {
//Test #1
System.out.println("using Iterator:");
Iterator<Integer> itr = list.iterator();
while (itr.hasNext()) {
Integer i = itr.next();
System.out.print(i + " ");
}
//Test #2
System.out.println("\n\nusing for-each:");
for (Integer data : list) {
System.out.print(data + " ");
}
}
}
Output
using Iterator:
1 2 4 3
using for-each:
1 2 4 3
This will run in Java 7+. You can make it run on Java 5 and Java 6 also by substituting:
with
Unfortunately, the overhead of this is substantial. A HashMap<Integer, Integer> will require about 72 bytes per entry (e.g.
on 64-bit JVM with compressed pointers, and assuming integers larger than 256, and assuming 50% load of the map).
Because the actual data is only 8 bytes, this yields a massive overhead. Furthermore, it requires two level of indirection
(Map -> Entry -> Value) it is unnecessarily slow.
There exist several libraries with optimized collections for primitive data types (that require only ~16 bytes per entry at
50% load, i.e. 4x less memory, and one level of indirection less), that can yield substantial performance benefits when
using large collections of primitive values in Java.
sort(List<T> list) applicable to lists where T extends Comparable<? super T>, and sort(List<T>
list, Comparator<? super T> c) applicable to lists of any type.
Applying the former requires amending the class of list elements being sorted, which is not always possible. It
might also be undesirable as although it provides the default sorting, other sorting orders may be required in
different circumstances, or sorting is just a one off task.
Consider we have a task of sorting objects that are instances of the following class:
@Override
public String toString() {
return String.format("%s:%d", username, id);
}
}
In order to use Collections.sort(List<User> list) we need to modify the User class to implement the Comparable
interface. For example
@Override
public String toString() {
return String.format("%s:%d", username, id);
}
@Override
/** The natural ordering for 'User' objects is by the 'id' field. */ public int
compareTo(User o) {
return id.compareTo(o.id);
}
}
With the modification above, the we can easily sort a list of User objects based on the classes natural ordering. (In this
case, we have defined that to be ordering based on id values). For example:
System.out.print(users);
// [B:25, C:28, A:33]
However, suppose that we wanted to sort User objects by name rather than by id. Alternatively, suppose that we had
not been able to change the class to make it implement Comparable.
This is where the sort method with the Comparator argument is useful:
In Java 8 you can use a lambda instead of an anonymous class. The latter reduces to a one-liner:
Further, there Java 8 adds a default sort method on the List interface, which simplifies sorting even more.
That is:
These are all of the public classes in Java SE 8 that implement the java.util.List interface:
Abstract Classes:
AbstractList
AbstractSequentialList
Concrete Classes:
ArrayList
AttributeList
CopyOnWriteArrayList
LinkedList
RoleList
RoleUnresolvedList
Stack
Vector
ArrayList is a resizable-array implementation of the List interface. Storing the list into an array, ArrayList provides
methods (in addition to the methods implementing the List interface) for manipulating the size of the array.
List<Integer> myList = new ArrayList<Integer>(100); // Constructs an empty list with the specified initial capacity.
- PROS:
The size, isEmpty, get, set, iterator, and listIterator operations run in constant time. So getting and setting each
element of the List has the same time cost:
int e1 = myList.get(0); // \
int e2 = myList.get(10); // | => All the same constant cost => O(1)
myList.set(2,10); // /
- CONS:
Being implemented with an array (static structure) adding elements over the size of the array has a big cost due to the
fact that a new allocation need to be done for all the array. However, from documentation:
The add operation runs in amortized constant time, that is, adding n elements requires O(n) time
AttributeList
CopyOnWriteArrayList
On coming
LinkedList
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable
LinkedList is implemented by a doubly-linked list a linked data structure that consists of a set of sequentially linked
records called nodes.
- PROS:
Adding or removing an element to the front of the list or to the end has constant time.
myList.add(10); // \
myList.add(0,2); // | => constant time => O(1)
myList.remove(); // /
Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the
specified index.
myList.get(10); // \
myList.add(11,25); // | => worst case done in O(n/2)
myList.set(15,35); // /
RoleList
On coming
RoleUnresolvedList
On coming
Stack
On coming
On coming
Example:
Consider an ArrayList containing the elements "Program starting!", "Hello world!" and "Goodbye world!"
If we know the index of the element we want to replace, we can simply use set as follows:
If we don't know the index, we can search for it first. For example:
Notes:
If you want an unmodifiable list with one item you can use:
Reversing a list:
Collections.reverse(ls);
The rotate method requires an integer argument. This is how many spots to move it along the line by. An example of
this is below:
Using the same list above, we can shuffle the elements in a list:
Collections.shuffle(ls);
We can also give it a java.util.Random object that it uses to randomly place objects in spots:
It extends AbstractList class and implements List interface. An ArrayList can contain duplicate elements where it maintains
insertion order. It should be noted that the class ArrayList is non-synchronized, so care should be taken when handling
concurrency with ArrayList. ArrayList allows random access because array works at the index basis. Manipulation is slow
in ArrayList because of shifting that often occurs when an element is removed from the array list.
The type of the ArrayList can be any Object. The type can't be a primitive type (use their wrapper classes instead).
myArrayList.add(element);
myArrayList.remove(element);
To create a list you need a type (any class, e.g. String). This is the type of your List. The List will only store objects of the
specified type. For example:
List<String> strings;
Can store "string1", "hello world!", "goodbye", etc, but it can't store 9.2, however:
List<Double> doubles;
If you try to add something to the lists above you will get a NullPointerException, because strings and doubles
List is an interface, which means that does not have a constructor, rather methods that a class must override.
ArrayList is the most commonly used List, though LinkedList is also common. So we initialise our list like this:
or
or
The Collections class provides two useful methods for creating Lists without a List variable:
addAll(L, T...): adds all the specified elements to the list passed as the first parameter.
Examples:
add(T type)
add(int index, T type)
remove(Object o)
remove(int index)
get(int index)
set(int index, E element)
int indexOf(Object o)
int lastIndexOf(Object o)
And we wanted to add the strings "Hello world!" and "Goodbye world!" to it, we would do it as such:
strings.add("Hello world!");
strings.add("Goodbye world!");
And our list would contain the two elements. Now lets say we wanted to add "Program starting!" at the front of the list.
We would do this like this:
Now, if we wanted to remove the "Goodbye world!" line, we could do it like this:
strings.remove("Goodbye world!");
And if we wanted to remove the first line (which in this case would be "Program starting!", we could do it like this:
strings.remove(0);
Note:
Adding and removing list elements modify the list, and this can lead to a ConcurrentModificationException if the list is
being iterated concurrently.
Adding and removing elements can be O(1) or O(N) depending on the list class, the method used, and
whether you are adding / removing an element at the start, the end, or in the middle of the list.
In order to retrieve an element of the list at a specified position you can use the E get(int index); method of the
List API. For example:
strings.get(0);
You can replace any element at a specified position by using the set(int index, E element);. For example:
strings.set(0,"This is a replacement");
This will set the String "This is a replacement" as the first element of the list.
Note: The set method will overwrite the element at the position 0. It will not add the new String at the position 0 and
push the old one to the position 1.
The int indexOf(Object o); returns the position of the first occurrence of the object passed as argument. If there are no
occurrences of the object in the list then the -1 value is returned. In continuation of the previous example if you call:
strings.indexOf("This is a replacement")
the 0 is expected to be returned as we set the String "This is a replacement" in the position 0 of our list. In case where
there are more than one occurrence in the list when int indexOf(Object o); is called then as mentioned
strings.add("This is a replacement");
strings.lastIndexOf("This is a replacement");
The best way to iterate over each element is by using a for-each loop:
hello,
how
are
you?
To print them all in the same line, you can use a StringBuilder:
Will print:
Alternatively, you can use element indexing ( as described in Accessing element at ith Index from ArrayList ) to
iterate a list. Warning: this approach is inefficient for linked lists.
List.removeAll(Collection c);
#Example:
numbersB.removeAll(numbersA);
System.out.println("B cleared: " + numbersB);
}
[1, 3, 4, 7, 5, 2]
Set have its implementation in various classes like HashSet, TreeSet, LinkedHashSet.
For example:
HashSet:
Here T can be String, Integer or any other object. HashSet allows for quick lookup of O(1) but does not sort the data
added to it and loses the insertion order of items.
TreeSet:
It stores data in a sorted manner sacrificing some speed for basic operations which take O(lg(n)). It does not
maintain the insertion order of items.
LinkedHashSet:
It is a linked list implementation of HashSet Once can iterate over the items in the order they were added. Sorting is not
provided for its contents. O(1) basic operations are provided, however there is higher cost than HashSet in maintaining
the backing linked list.
A set is a data structure which contains a set of elements with an important property that no two elements in the set
are equal.
Types of Set:
Creating a set
Set<Integer> linkedHashSet = new LinkedHashSet<Integer>(); //Creates a empty Set of Integers, with predictable iteration order
set = [12,13]
set = []
Existence of an element in the set can be checked using the contains() method
Output: False
Output: True
Output: 0
Example:
Output:
Using guava:
Using Streams:
Since Map is an interface, then you need to instantiate a concrete implementation of that interface in order to use it; there
are several Map implementations, and mostly used are the java.util.HashMap and java.util.TreeMap
Iterator<Integer> it = map.keySet().iterator();
while (it.hasNext()) {
Integer key = it.next();
sum += key + map.get(key);
}
map.entrySet()
.stream()
.parallel()
.forEach(e -> sum += e.getKey() + e.getValue());
x: Size of Map
f(x): Benchmark Score (μs/op)
1. Declaring HashMap
To put a value in the HashMap, we have to call put method on the HashMap object by passing the Key and the
Value as parameters.
myMap.put("key1", 1);
myMap.put("key2", 2);
If you call the put method with the Key that already exists in the Map, the method will override its value and return the
old value.
For getting the value from a HashMap you have to call the get method, by passing the Key as a parameter.
If you pass a key that does not exists in the HashMap, this method will return null
myMap.containsKey(varKey);
myMap.containsValue(varValue);
The above methods will return a boolean value true or false if key, value exists in the Map or not.
Using getOrDefault
Returns the value mapped to the key, or if the key is not present, returns the default value
Using forEach
Allows to perform the operation specified in the 'action' on each Map Entry
Using replaceAll
Using putIfAbsent
Key-Value pair is added to the map, if the key is not present or mapped to null
Using remove
Removes the key only if its associated with the given value
Using replace
If the key is present then the value is replaced by new-value. If the key is not present, does nothing.
Using computeIfAbsent
This method adds an entry in the Map. the key is specified in the function and the value is the result of the
application of the mapping function
Using computeIfPresent
This method adds an entry or modifies an existing entry in the Map. Does nothing if an entry with that key is not
present
Using compute
This method replaces the value of a key by the newly computed value
Adds the key-value pair to the map, if key is not present or value for the key is null Replaces the value with the
newly computed value, if the key is present Key is removed from the map , if new value computed is null
//Adds the key-value pair to the map, if key is not present or value for the key is null
map.merge("kelly", 50 , (k,v)->map.get("john")+10); // {john=20, paul=30, peter=40, kelly=50}
//Replaces the value with the newly computed value, if the key is present
map.merge("peter", 50 , (k,v)->map.get("john")+10); //{john=20, paul=30, peter=30, kelly=50}
Prints:
Darin Dimitrov
Jon Skeet
BalusC
keySet() provides the keys of the map as a Set. Set is used as the keys cannot contain duplicate values. Iterating through
the set yields each key in turn. HashMaps are not ordered, so in this example the keys may be returned in any order.
Prints:
715567
927654
708826
values() returns the values of the map as a Collection. Iterating through the collection yields each value in turn.
Again, the values may be returned in any order.
Prints:
entrySet() returns a collection of Map.Entry objects. Map.Entry gives access to the key and value for each entry.
numbers.putAll(other_numbers)
"One" -> 1
"Two" -> 2
"Three" -> 4 //old value 3 was overwritten by new value 4
If you want to combine values instead of overwriting them, you can use Map.merge, added in Java 8, which uses a
user-provided BiFunction to merge values for duplicate keys. merge operates on individual keys and values, so you'll
need to use a loop or Map.forEach. Here we concatenate strings for duplicate keys:
If you want to enforce the constraint there are no duplicate keys, you can use a merge function that throws an
AssertionError:
mapA.forEach((k, v) ->
mapB.merge(k, v, (v1, v2) ->
{throw new AssertionError("duplicate values for key: "+k);}));
String currentVal;
Map<Integer, String> map = new TreeMap<>();
currentVal = map.put(1, "First element.");
System.out.println(currentVal);// Will print null
currentVal = map.put(2, "Second element.");
System.out.println(currentVal); // Will print null yet again
currentVal = map.put(2, "This will replace 'Second element'");
System.out.println(currentVal); // will print Second element.
System.out.println(map.size()); // Will print 2 as key having
// value 2 was replaced.
map.putAll(map2);
System.out.println(map.size());
Output:
To add many items you can use an inner classes like this:
put(4, "low");
put(1, "too slow");
}};
Keep in mind that creating an anonymous inner class is not always efficient and can lead to memory leaks so when
possible, use an initializer block instead:
static {
Now no inner classes are created so we can avoid memory leaks put(5, "high");
put(4, "low");
put(1, "too slow");
}
The example above makes the map static. It can also be used in a non-static context by removing all occurrences of
static.
In addition to that most implementations support putAll, which can add all entries in one map to another like this:
another.putAll(one);
Maps stores key/value pairs, where each key has an associated value. Given a particular key, the map can look up the
associated value very quickly.
Maps, also known as associate array, is an object that stores the data in form of keys and values. In Java, maps are
represented using Map interface which is not an extension of the collection interface.
Way 1:
Way 2:
Way 3:
Way 4:
Way 5:
//Java 8
final Map<String, String> map =
Arrays.stream(new String[][] {
{ "name", "A" },
{ "address", "Malviya-Nagar" }, { "city",
"jaipur" },
}).collect(Collectors.toMap(m -> m[0], m -> m[1]));
System.out.println(map);
//This way for initial a map in outside the function final static
Map<String, String> map;
static
{
map = new HashMap<String, String>();
map.put("a", "b");
map.put("c", "d");
}
Any attemts to modify the map will result in throwing the UnsupportedOperationException.
UnsupportedOperationException
//and etc
if (num.containsKey("one")) {
System.out.println(num.get("one")); // => first
}
Maps can contain null values
For maps, one has to be carrefull not to confuse "containing a key" with "having a value". For example, HashMaps can
contain null which means the following is perfectly normal behavior :
2. Override
HashMap is used as an example. Other implementations that implement the Map interface may be used as well.
map.clear();
System.out.println(map.size()); // => 0
class MyKey {
private String name;
MyKey(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof MyKey) {
return this.name.equals(((MyKey)obj).name);
}
return false;
}
@Override
public int hashCode() {
return this.name.hashCode();
}
}
hashCode will decide which hash bucket the key belongs to and equals will decide which object inside that hash
bucket.
The important points about Java LinkedHashMap class are: A LinkedHashMap contains values based on the key. It
contains only unique elements. It may have one null key and multiple null values. It is same as HashMap instead
maintains insertion order.
Is Hash table and Linked list implementation of the Map interface, with predictable iteration order.
Methods:
void clear().
boolean containsKey(Object key).
Object get(Object key).
protected boolean removeEldestEntry(Map.Entry eldest)
Example:
Implementation of Map.
stores only weak references to its keys.
Weak References : The objects that are referenced only by weak references are garbage collected eagerly; the GC
won’t wait until it needs memory in that case.
If the Java memory manager no longer has a strong reference to the object specified as a key, then the entry in the map
will be removed in WeakHashMap.
Example:
hashMap.put(keyHashMap, "Ankita");
weakHashMap.put(keyWeakHashMap, "Atul");
System.gc();
System.out.println("Before: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map
value:"+weakHashMap.get("keyWeakHashMap"));
keyHashMap = null;
keyWeakHashMap = null;
System.gc();
Calling size() method on HashMap object will return the same number of key-value pairs. size will decrease only if
remove() method is called explicitly on the HashMap object.
Because the garbage collector may discard keys at anytime, a WeakHashMap may behave as though an unknown
thread is silently removing entries. So it is possible for the size method to return smaller values over time.So, in
WeakHashMap size decrease happens automatically.
Comparator comparator( ).
Object firstKey( ).
SortedMap headMap(Object end).
Object lastKey( ).
SortedMap subMap(Object start, Object end).
SortedMap tailMap(Object start).
Example
Get an iterator
Iterator i = set.iterator();
Display elements
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue());
}
System.out.println();
TreeMap is implemented as a Red-Black tree, which provides O(log n) access times. TreeSet is implemented using a
TreeMap with dummy values.
Version ≥ Java SE 7
TreeMap<Integer, String> treeMap = new TreeMap<>();
Version < Java SE 7
TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>();
treeMap.put(10, "ten");
treeMap.put(4, "four");
treeMap.put(1, "one");
treeSet.put(12, "twelve");
Once we have a few elements in the map, we can perform some operations:
We can also iterate over the map elements using either an Iterator, or a foreach loop. Note that the entries are
printed according to their natural ordering, not the insertion order:
Version ≥ Java SE 7
for (Entry<Integer, String> entry : treeMap.entrySet()) {
System.out.print(entry + " "); //prints 1=one 4=four 10=ten 12=twelve
}
Version ≥ Java SE 7
TreeSet<Integer> treeSet = new TreeSet<>();
Version < Java SE 7
TreeSet<Integer> treeSet = new TreeSet<Integer>();
treeSet.add(10);
treeSet.add(4);
treeSet.add(1);
Once we have a few elements in the set, we can perform some operations:
System.out.println(treeSet.first()); // Prints 1
System.out.println(treeSet.last()); // Prints 12
System.out.println(treeSet.size()); // Prints 4, since there are 4 elemens in the set
System.out.println(treeSet.contains(12)); // Prints true
System.out.println(treeSet.contains(15)); // Prints false
We can also iterate over the map elements using either an Iterator, or a foreach loop. Note that the entries are
printed according to their natural ordering, not the insertion order:
Version ≥ Java SE 7
for (Integer i : treeSet) {
System.out.print(i + " "); //prints 1 4 10 12
}
at java.util.TreeMap.compare(TreeMap.java:1294)
at java.util.TreeMap.put(TreeMap.java:538)
at java.util.TreeSet.add(TreeSet.java:255)
To fix that, let's assume that we want to order Person instances based on the order of their ids (private int id).
We could do it in one of two ways:
@Override
public int compareTo(Person o) {
return Integer.compare(this.id, o.id); //Compare by id
}
}
Version ≥ Java SE 8
TreeSet<Person> treeSet = new TreeSet<>((personA, personB) -> Integer.compare(personA.getId(), personB.getId()));
It's very important not to modify any fields used for ordering once an instance has been inserted into a
TreeSet/TreeMap. In the above example, if we change the id of a person that's already inserted into the
collection, we might run into unexpected behavior.
It's important to implement the comparison properly and consistently. As per the Javadoc:
The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that
x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.)
The implementor must also ensure that the relation is transitive: (x.compareTo(y)>0 &&
y.compareTo(z)>0) implies x.compareTo(z)>0.
Finally, the implementor must ensure that x.compareTo(y)==0 implies that sgn(x.compareTo(z)) ==
sgn(y.compareTo(z)), for all z.
Both TreeMap and TreeSet are safe when read, even concurrently, by multiple threads. So if they have been created and
populated by a single thread (say, at the start of the program), and only then read, but not modified by multiple threads,
there's no reason for synchronization or locking.
However, if read and modified concurrently, or modified concurrently by more than one thread, the collection might
throw a ConcurrentModificationException or behave unexpectedly. In these cases, it's imperative to
synchronize/lock access to the collection using one of the following approaches:
This will provide a SortedSet/SortedMap implementation backed by the actual collection, and synchronized on
some mutex object. Note that this will synchronize all read and write access to the collection on a single lock, so
even concurrent reads would not be possible.
...
//Thread 1
synchronized (set) {
set.add(4);
}
...
//Thread 2
synchronized (set) {
set.remove(5);
}
...
//Thread 1
lock.writeLock().lock();
set.add(4);
lock.writeLock().unlock();
...
//Thread 2
lock.readLock().lock();
set.contains(5);
lock.readLock().unlock();
As opposed to the previous synchronization methods, using a ReadWriteLock allows multiple threads to read from the
map concurrently.
//The PriorityQueue sorts the elements by using compareTo method of the Integer Class //The head of this
queue is the least element with respect to the specified ordering System.out.println( queue ); //The Output: [1, 2,
3, 9, 3, 8]
queue.remove();
System.out.println( queue ); //The Output: [2, 3, 3, 9, 8] queue.remove();
The Deque inherits the Queue interface which means the regular methods remain, however the Deque interface offers
additional methods to be more flexible with a queue. The additional methods really speak for them self if you know how a
queue works, since those methods are intended to add more flexibility:
Of course the same options for offer, poll and peek are available, however they do not work with exceptions but rather
with special values. There is no point in showing what they do here.
To add elements to the tail of a Deque you call its add() method. You can also use the addFirst() and addLast() methods,
which add elements to the head and tail of the deque.
You can peek at the element at the head of the queue without taking the element out of the queue. This is done via the
element() method. You can also use the getFirst() and getLast() methods, which return the first and last element in the
Deque. Here is how that looks:
To remove elements from a deque, you call the remove(), removeFirst() and removeLast() methods. Here are a few
examples:
In Java, Stacks are a LIFO (Last In, First Out) Data structure for objects.
Stack API
st.push(10);
System.out.println("10 was pushed to the stack");
System.out.println("stack: " + st);
st.push(15);
System.out.println("15 was pushed to the stack");
System.out.println("stack: " + st);
st.push(80);
System.out.println("80 was pushed to the stack");
System.out.println("stack: " + st);
st.pop();
System.out.println("15 was popped from the stack");
System.out.println("stack: " + st);
st.pop();
System.out.println("10 was popped from the stack");
System.out.println("stack: " + st);
if(st.isEmpty())
{
System.out.println("empty stack");
}
}
}
This returns:
stack: []
10 was pushed to the stack
stack: [10]
15 was pushed to the stack
stack: [10, 15]
80 was pushed to the stack
stack: [10, 15, 80]
80 was popped from the stack
stack: [10, 15]
15 was popped from the stack
stack: [10]
10 was popped from the stack
stack: []
empty stack
BlockingQueue methods come in four forms, with different ways of handling operations that cannot be satisfied
immediately, but may be satisfied at some point in the future: one throws an exception, the second returns a special
value (either null or false, depending on the operation), the third blocks the current thread indefinitely until the operation
can succeed, and the fourth blocks for only a given maximum time limit before giving up.
A BlockingQueue can be bounded or unbounded. A bounded BlockingQueue is one which is initialized with initial
Any calls to a put() method will be blocked if the size of the queue is equal to the initial capacity defined.
An unbounded Queue is one which is initialized without capacity, actually by default it initialized with
Integer.MAX_VALUE.
ArrayBlockingQueue
LinkedBlockingQueue
PriorityBlockingQueue
In the example below, with offer() method, the elements are inserted into the LinkedList. This insertion operation is called
enqueue. In the while loop below, the elements are removed from the Queue based on FIFO. This operation is called
dequeue.
while ( !queue.isEmpty() ) {
System.out.println( queue.poll() );
}
first element
As seen in the output, the first inserted element "first element" is removed firstly, "second element" is removed in the
second place etc.
A Queue is a collection for holding elements prior to processing. Queues typically, but not necessarily, order
elements in a FIFO (first-in-first-out) manner.
Head of the queue is the element that would be removed by a call to remove or poll. In a FIFO queue, all new
elements are inserted at the tail of the queue.
remove();
poll();
element();
peek();
}
The name deque is short for "double ended queue" and is usually pronounced "deck".
Most Deque implementations place no fixed limits on the number of elements they may contain, but this interface
supports capacity-restricted deques as well as those with no fixed size limit.
The Deque interface is a richer abstract data type than both Stack and Queue because it implements both stacks and
queues at same time
//Retrieves, but does not remove, the first element of this deque.
Object firstItem = deque.getFirst();
//Retrieves, but does not remove, the last element of this deque.
Object lastItem = deque.getLast();
While the enum constants don't necessarily need to be in all-caps, it is Java convention that names of constants are
entirely uppercase, with words separated by underscores.
/**
This enum is declared in the Season.java file.
*/
public enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
/**
This enum is declared inside the Day.java file and
cannot be accessed outside because it's declared as private.
*/
private enum Season {
WINTER,
SPRING,
SUMMER,
FALL
/**
Constructor
*/
public Day() {
Illegal. Compilation error enum
Season {
WINTER,
SPRING,
SUMMER,
FALL
}
}
Every constant of enum is public, static and final by default. As every constant is static, they can be accessed directly
using the enum name.
Note: this method allocates a new array of values each time it is called.
Another way to compare enum constants is by using equals() as below, which is considered bad practice as you can
easily fall into pitfalls as follows:
Season.FALL.equals(Season.FALL); // true
Season.FALL.equals(Season.WINTER); // false
Season.FALL.equals("FALL"); // false and no compiler error
Furthermore, although the set of instances in the enum cannot be changed at run-time, the instances themselves are
not inherently immutable because like any other class, an enum can contain mutable fields as is demonstrated below.
// Usage:
MutableExample.A.print(); // Outputs 0
MutableExample.A.increment();
MutableExample.A.print(); // Outputs 1 -- we've changed a field
MutableExample.B.print(); // Outputs 0 -- another instance remains unchanged
However, a good practice is to make enum instances immutable, i.e. when they either don't have any additional fields
or all such fields are marked as final and are immutable themselves. This will ensure that for a lifetime of the
application an enum won't leak any memory and that it is safe to use its instances across all threads.
Enums implicitly implement Serializable and Comparable because the Enum class does:
Coin(int value) {
this.value = value;
}
It is recommended that you keep all fields private and provide getter methods, as there are a finite number of
instances for an enum.
If you were to implement an Enum as a class instead, it would look like this:
public class Coin<T extends Coin<T>> implements Comparable<T>, Serializable{ public static
final Coin PENNY = new Coin(1);
public static final Coin NICKEL = new Coin(5);
public static final Coin DIME = new Coin(10);
public static final Coin QUARTER = new Coin(25);
Enum constants are technically mutable, so a setter could be added to change the internal structure of an enum
constant. However, this is considered very bad practice and should be avoided.
Coin(int value){
this.value = value;
}
...
You may define multiple constructors in the same enum. When you do, the arguments you pass in your enum
declaration decide which constructor is called:
Coin(int value){
this(value, false);
}
...
Note: All non-primitive enum fields should implement Serializable because the Enum class does.
enum Action {
DODGE {
This allows for each enum member to define its own behaviour for a given operation, without having to switch on types
in a method in the top-level definition.
Note that this pattern is a short form of what is typically achieved using polymorphism and/or implementing
interfaces.
import java.util.function.Predicate;
import java.util.regex.Pattern;
@Override
public boolean test(final String input) {
return this.pattern.matcher(input).matches();
}
}
import java.util.function.Predicate;
INSTANCE;
private Attendant() {
// perform some initialization routine
}
According to "Effective Java" book by Joshua Bloch, a single-element enum is the best way to implement a singleton.
This approach has following advantages:
thread safety
guarantee of single instantiation
out-of-the-box serialization
And as shown in the section implements interface this singleton might also implement one or more interfaces.
Let's have a method that returns the enum in the opposite direction:
This can be improved further through the use of fields and static initializer blocks:
static {
NORTH.opposite = SOUTH;
SOUTH.opposite = NORTH;
WEST.opposite = EAST;
EAST.opposite = WEST;
}
}
In this example, the opposite direction is stored in a private instance field opposite, which is statically initialized the first
time a Direction is used. In this particular case (because NORTH references SOUTH and conversely), we cannot use
Enums with constructors here (Constructors NORTH(SOUTH), SOUTH(NORTH), EAST(WEST), WEST(EAST) would be more
elegant and would allow opposite to be declared final, but would be self-referential and therefore are not allowed).
Just as enum can be used for singletons (1 instance classes), it can be used for utility classes (0 instance classes). Just
make sure to terminate the (empty) list of enum constants with a ;.
See the question Zero instance enum vs private constructors for preventing instantiation for a discussion on pro's and
con's compared to private constructors.
/**
United States coins
*/
public enum Coins {
/**
One-cent coin, commonly known as a penny,
is a unit of currency equaling one-hundredth
of a United States dollar
*/
PENNY(1),
/**
A nickel is a five-cent coin equaling
five-hundredth of a United States dollar
*/
NICKEL(5),
/**
The dime is a ten-cent coin refers to
one tenth of a United States dollar
*/
DIME(10),
/**
The quarter is a US coin worth 25 cents,
one-fourth of a United States dollar
Coins(int value){
this.value = value;
}
Suppose three piano students - John, Ben and Luke - are defined in an enum named PianoClass, as follows:
enum PianoClass {
JOHN, BEN, LUKE;
public String getSex() {
return "Male";
}
public String getLevel() {
return "Beginner";
}
}
And one day two other students arrive - Rita and Tom - with a sex (Female) and level (Intermediate) that do not
match the previous ones:
enum PianoClass2 {
JOHN, BEN, LUKE, RITA, TOM;
public String getSex() {
return "Male"; // issue, Rita is a female
}
public String getLevel() {
return "Beginner"; // issue, Tom is an intermediate student
}
}
so that simply adding the new students to the constant declaration, as follows, is not correct:
It's possible to define a specific behavior for each of the constant, Rita and Tom, which overrides the PianoClass2
default behavior as follows:
enum PianoClass3 {
JOHN, BEN, LUKE,
RITA {
@Override
and now Tom's level and Rita's sex are as they should be:
Another way to define content specific body is by using constructor, for instance:
enum Friend {
MAT("Male"),
JOHN("Male"),
JANE("Female");
Friend(String gender) {
this.gender = gender;
}
and usage:
/**
Print out all the values in this enum.
*/
public static void printAllDays() { for(Day day
: Day.values()) {
System.out.println(day.name());
}
}
}
This way, any enum tagged by (implementing) the interface can be used as a parameter, allowing the programmer to
create a variable amount of enums that will be accepted by the method. This can be useful, for example, in APIs where
there is a default (unmodifiable) enum and the user of these APIs want to "extend" the enum with more values.
Sample which shows how to use the enums - note how printEnum() accepts values from both enum types:
printEnum(DefaultValues.VALUE_ONE); // VALUE_ONE
printEnum(DefaultValues.VALUE_TWO); // VALUE_TWO
printEnum(ExtendedValues.VALUE_THREE); // VALUE_THREE
printEnum(ExtendedValues.VALUE_FOUR); // VALUE_FOUR
Note: This pattern does not prevent you from redefining enum values, which are already defined in one enum, in another
enum. These enum values would be different instances then. Also, it is not possible to use switch-on-enum since all we
have is the interface, not the real enum.
enum Day {
GOOD, AVERAGE, WORST;
}
if (day.equals(Day.GOOD)) {//NullPointerException!
System.out.println("Good Day!");
}
}
}
To group, complement, range the enum values we have EnumSet class which contains different methods.
EnumSet#of : Set of specific enums without any range. Multiple overloaded of methods are there.
EnumSet#complementOf : Set of enum which is complement of enum values provided in method parameter
enum Page {
A1, A2, A3, A4, A5, A6, A7, A8, A9, A10
}
if (range.contains(Page.A4)) {
System.out.println("Range contains A4");
}
if (of.contains(Page.A1)) {
System.out.println("Of contains A1");
}
}
}
An enum is compiled with a built-in static valueOf() method which can be used to lookup a constant by its name:
Both of these valueOf() methods will throw an IllegalArgumentException if the specified enum does not have a constant
with a matching name.
The Guava library provides a helper method Enums.getIfPresent() that returns a Guava Optional to eliminate explicit
exception handling:
Coin(int value){
this.value = value;
}
Here we defined an Enum called Coin which represent its value. With the method isGreaterThan we can compare two
enums:
Assume we have:
name() is an internal method in enum that returns the String representation of the enum, the return String
represents exactly how the enum value was defined.
For example:
System.out.println(Fruit.BANANA.name()); // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.name()); // "GRAPE_FRUIT"
However, toString() is likely overridden by developers to make it print a more user friendly String
Don't use toString() if you want to do checking in your code, name() is much more stable for that. Only use
toString() when you are going to output the value to logs or stdout or something
By default:
System.out.println(Fruit.BANANA.toString()); // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "GRAPE_FRUIT"
enum Example {
ONE(1), TWO(2);
enum Example {
ONE(1), TWO(2);
enum Example {
ONE(1), TWO(2);
initialisisation:
K: It is the type of keys maintained by this map. V: It is the type of mapped values.
this.name = name;
this.author = author;
this.publisher = publisher;
this.quantity = quantity;
}
}
public class EnumMapExample {
Creating enum public
enum Key{
One, Two, Three };
}
}
When the ++ and -- operators follow variables, they are called post-increment and post-decrement respectively.
int a = 10;
a++; // a now equals 11
a--; // a now equals 10 again
When the ++ and -- operators precede the variables the operations are called pre-increment and pre-decrement
respectively.
int x = 10;
--x; // x now equals 9
++x; // x now equals 10
If the operator precedes the variable, the value of the expression is the value of the variable after being incremented
or decremented. If the operator follows the variable, the value of the expression is the value of the variable prior to
being incremented or decremented.
int x=10;
System.out.println("x=" + x + " x=" + x++ + " x=" + x); // outputs x=10 x=10 x=11
System.out.println("x=" + x + " x=" + ++x + " x=" + x); // outputs x=11 x=12 x=12
System.out.println("x=" + x + " x=" + x-- + " x=" + x); // outputs x=12 x=12 x=11
System.out.println("x=" + x + " x=" + --x + " x=" + x); // outputs x=11 x=10 x=10
Be careful not to overwrite post-increments or decrements. This happens if you use a post-in/decrement operator at the
end of an expression which is reassigned to the in/decremented variable itself. The in/decrement will not have an effect.
Even though the variable on the left hand side is incremented correctly, its value will be immediately overwritten with the
previously evaluated result from the right hand side of the expression:
int x = 0;
x = x++ + 1 + x++; // x = 0 + 1 + 1
do not do this - the last increment has no effect (bug!) System.out.println(x);
// prints 2 (not 3!)
Correct:
int x = 0;
x = x++ + 1 + x; // evaluates to x = 0 + 1 + 1
x++; // adds 1
System.out.println(x); // prints 3
As shown in the syntax, the Conditional Operator (also known as the Ternary Operator1) uses the ? (question mark) and :
(colon) characters to enable a conditional expression of two possible outcomes. It can be used to replace longer if-else
blocks to return one of two values based on condition.
Is equivalent to
if (testCondition) {
result = value1;
} else {
result = value2;
}
It can be read as “If testCondition is true, set result to value1; otherwise, set result to value2”.
For example:
Is equivalent to
int absValue; if
(a < 0) {
absValue = -a; }
else {
absValue = a;
}
System.out.println("abs = " + absValue); // prints "abs = 10"
Common Usage
You can use the conditional operator for conditional assignments (like null checking).
String x = "";
if (y != null) {
x = y.toString();
}
Since the Conditional Operator has the second-lowest precedence, above the Assignment Operators, there is rarely a
need for use parenthesis around the condition, but parenthesis is required around the entire Conditional Operator
construct when combined with other operators:
parenthesis required 7 * (a
> 0 ? 2 : 5)
Conditional operators nesting can also be done in the third part, where it works more like chaining or like a switch
statement.
a ? "a is true" :
b ? "a is false, b is true" :
c ? "a and b are false, c is true" :
"a, b, and c are false"
a ? x : (b ? y : (c ? z : w))
Footnote:
1 - Both the Java Language Specification and the Java Tutorial call the (? :) operator the Conditional Operator. The
Tutorial says that it is "also known as the Ternary Operator" as it is (currently) the only ternary operator defined by Java.
The "Conditional Operator" terminology is consistent with C and C++ and other languages with an equivalent operator.
The complement (~) operator is a unary operator that performs a bitwise or logical inversion of the bits of one
operand; see JLS 15.15.5..
The AND (&) operator is a binary operator that performs a bitwise or logical "and" of two operands; see JLS
15.22.2..
The OR (|) operator is a binary operator that performs a bitwise or logical "inclusive or" of two operands; see JLS
15.22.2..
The XOR (^) operator is a binary operator that performs a bitwise or logical "exclusive or" of two operands; see
JLS 15.22.2..
The logical operations performed by these operators when the operands are booleans can be summarized as
follows:
AB~AA&BA|BA^B
001 0 0 0
011 0 1 1
100 0 1 1
110 1 1 0
Note that for integer operands, the above table describes what happens for individual bits. The operators actually
operate on all 32 or 64 bits of the operand or operands in parallel.
The usual arithmetic conversions apply when the operands are integers. Common use-cases for the bitwise
operators
The ~ operator is used to reverse a boolean value, or change all the bits in an integer operand.
The | operator is used to combine the truth values of two operands. For example:
For more examples of the use of the bitwise operators, see Bit Manipulation
In the simple case, the Concatenation operator joins two strings to give a third string. For example:
When one of the two operands is not a string, it is converted to a String as follows:
An operand whose type is a primitive type is converted as if by calling toString() on the boxed value.
An operand whose type is a reference type is converted by calling the operand's toString() method. If the operand
is null, or if the toString() method returns null, then the string literal "null" is used instead.
For example:
int one = 1;
String s3 = "One is " + one; // s3 contains "One is 1"
String s4 = null + " is null"; // s4 contains "null is null"
String s5 = "{1} is " + new int[]{1}; // s5 contains something like
// "{} is [I@xxxxxxxx"
The explanation for the s5 example is that the toString() method on array types is inherited from
java.lang.Object, and the behavior is to produce a string that consists of the type name, and the object's identity
hashcode.
The Concatenation operator is specified to create a new String object, except in the case where the expression is a
Constant Expression. In the latter case, the expression is evaluated at compile type, and its runtime value is
As noted above, with the exception of constant expressions, each string concatenation expression creates a new
String object. Consider this code:
In the method above, each iteration of the loop will create a new String that is one character longer than the previous
iteration. Each concatenation copies all of the characters in the operand strings to form the new String. Thus, stars(N)
will:
create N new String objects, and throw away all but the last one,
copy N * (N + 1) / 2 characters, and
generate O(N^2) bytes of garbage.
This is very expensive for large N. Indeed, any code that concatenates strings in a loop is liable to have this problem.
A better way to write this would be as follows:
sb.append("*");
}
return sb.toString();
}
Ideally, you should set the capacity of the StringBuilder, but if this is not practical, the class will automatically grow the
backing array that the builder uses to hold characters. (Note: the implementation expands the backing array
exponentially. This strategy keeps that amount of character copying to a O(N) rather than O(N^2).)
Some people apply this pattern to all string concatenations. However, this is unnecessary because the JLS allows a
Java compiler to optimize string concatenations within a single expression. For example:
String s1 = ...;
String s2 = ...;
String test = "Hello " + s1 + ". Welcome to " + s2 + "\n";
(The JIT compiler may optimize that further if it can deduce that s1 or s2 cannot be null.) But note that this
optimization is only permitted within a single expression.
This is often incorrectly referred to as the "modulus" operator. "Remainder" is the term that is used by the JLS.
"Modulus" and "remainder" are not the same thing.
The operators require numeric operands and produce numeric results. The operand types can be any primitive numeric
type (i.e. byte, short, char, int, long, float or double) or any numeric wrapper type define in java.lang; i.e. (Byte, Character,
Short, Integer, Long, Float or Double.
The result type is determined base on the types of the operand or operands, as follows:
If either of the operands is a double or Double, then the result type is double.
Otherwise, if either of the operands is a float or Float, then the result type is float.
Otherwise, if either of the operands is a long or Long, then the result type is long.
Otherwise, the result type is int. This covers byte, short and char operands as well as `int.
The result type of the operation determines how the arithmetic operation is performed, and how the operands are
handled
If the result type is double, the operands are promoted to double, and the operation is performed using 64-bit
(double precision binary) IEE 754 floating point arithmetic.
If the result type is float, the operands are promoted to float, and the operation is performed using 32-bit (single
precision binary) IEE 754 floating point arithmetic.
If the result type is long, the operands are promoted to long, and the operation is performed using 64-bit signed
twos-complement binary integer arithmetic.
If the result type is int, the operands are promoted to int, and the operation is performed using 32-bit signed
twos-complement binary integer arithmetic.
If the operand type is a wrapper type, the operand value is unboxed to a value of the corresponding primitive type.
If necessary, the primitive type is promoted to the required type:
Promotion of integers to int or long is loss-less.
Promotion of float to double is loss-less.
Promotion of an integer to a floating point value can lead to loss of precision. The conversion is
performed using IEE 768 "round-to-nearest" semantics.
The / operator divides the left-hand operand n (the dividend) and the right-hand operand d (the divisor) and
produces the result q (the quotient).
Java integer division rounds towards zero. The JLS Section 15.17.2 specifies the behavior of Java integer division as
follows:
The quotient produced for operands n and d is an integer value q whose magnitude is as large as possible
while satisfying |d ⋅ q| ≤ |n|. Moreover, q is positive when |n| ≥ |d| and n and d have the same sign, but q is
negative when |n| ≥ |d| and n and d have opposite signs.
If the n is MIN_VALUE, and the divisor is -1, then integer overflow occurs and the result is MIN_VALUE. No
exception is thrown in this case.
If d is 0, then `ArithmeticException is thrown.
Java floating point division has more edge cases to consider. However the basic idea is that the result q is the value that
is closest to satisfying d . q = n.
Floating point division will never result in an exception. Instead, operations that divide by zero result in an INF and NaN
values; see below.
Unlike C and C++, the remainder operator in Java works with both integer and floating point operations.
For integer cases, the result of a % b is defined to be the number r such that (a / b) * b + r is equal to a, where /, * and +
are the appropriate Java integer operators. This applies in all cases except when b is zero. That case, remainder results
in an ArithmeticException.
It follows from the above definition that a % b can be negative only if a is negative, and it be positive only if a is
positive. Moreover, the magnitude of a % b is always less than the magnitude of b.
Floating point remainder operation is a generalization of the integer case. The result of a % b is the remainder r is
defined by the mathematical relation r = a - (b ⋅ q) where:
q is an integer,
it is negative only if a / b is negative an positive only if a / b is positive, and
its magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of a and b.
Important note:
The result of a floating-point remainder operation as computed by % is not the same as that produced by the
remainder operation defined by IEEE 754. The IEEE 754 remainder may be computed using the
Math.IEEEremainder library method.
Integer Overflow
Java 32 and 64 bit integer values are signed and use twos-complement binary representation. For example, the
range of numbers representable as (32 bit) int -231 through +231 - 1.
When you add, subtract or multiple two N bit integers (N == 32 or 64), the result of the operation may be too large to
represent as an N bit integer. In this case, the operation leads to integer overflow, and the result can be computed as
follows:
The mathematical operation is performed to give a intermediate two's-complement representation of the entire
number. This representation will be larger than N bits.
The bottom 32 or 64 bits of the intermediate representation are used as the result.
It should be noted that integer overflow does not result in exceptions under any circumstances.
Java uses IEE 754 floating point representations for float and double. These representations have some special
values for representing values that fall outside of the domain of Real numbers:
The "infinite" or INF values denote numbers that are too large. The +INF value denote numbers that are too large
and positive. The -INF value denote numbers that are too large and negative.
The "indefinite" / "not a number" or NaN denote values resulting from meaningless operations.
The INF values are produced by floating operations that cause overflow, or by division by zero.
The NaN values are produced by dividing zero by zero, or computing zero remainder zero.
Surprisingly, it is possible perform arithmetic using INF and NaN operands without triggering exceptions. For
example:
For full details, please refer to the relevant subsections of JLS 15. Note that this is largely "academic". For typical
calculations, an INF or NaN means that something has gone wrong; e.g. you have incomplete or incorrect input data, or
the calculation has been programmed incorrectly.
The << or left shift operator shifts the value given by the first operand leftwards by the number of bit positions given
by the second operand. The empty positions at the right end are filled with zeros.
The '>>' or arithmetic shift operator shifts the value given by the first operand rightwards by the number of bit
positions given by the second operand. The empty positions at the left end are filled by copying the left-most bit.
This process is known as sign extension.
The '>>>' or logical right shift operator shifts the value given by the first operand rightwards by the number of bit
positions given by the second operand. The empty positions at the left end are filled with zeros.
Notes:
These operators require an int or long value as the first operand, and produce a value with the same type as the
first operand. (You will need to use an explicit type cast when assigning the result of a shift to a byte, short or char
variable.)
If you use a shift operator with a first operand that is a byte, char or short, it is promoted to an int and the
operation produces an int.)
The second operand is reduced modulo the number of bits of the operation to give the amount of the shift. For
more about the mod mathematical concept, see Modulus examples.
The bits that are shifted off the left or right end by the operation are discarded. (Java does not provide a
primitive "rotate" operator.)
The arithmetic shift operator is equivalent dividing a (two's complement) number by a power of 2.
The left shift operator is equivalent multiplying a (two's complement) number by a power of 2.
The following table will help you see the effects of the three shift operators. (The numbers have been expressed in
binary notation to aid vizualization.)
Example:
}
}
true
This operator will still return true if the object being compared is the assignment compatible with the type on the right.
Example:
class Vehicle {}
true
Section 40.8: The Assignment Operators (=, +=, -=, *=, /=, %=,
<<=, >>= , >>>=, &=, |= and ^=)
The left hand operand for these operators must be a either a non-final variable or an element of an array. The right hand
operand must be assignment compatible with the left hand operand. This means that either the types must be the same,
or the right operand type must be convertible to the left operands type by a combination of boxing, unboxing or widening.
(For complete details refer to JLS 5.2.)
The precise meaning of the "operation and assign" operators is specified by JLS 15.26.2 as:
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is
the type of E1, except that E1 is evaluated only once.
+=
The "add and assign" operator: adds the value of right hand operand to the value of the left hand operand and
assigns the result to left hand operand. If the left hand operand has type String, then this a "concatenate and assign"
operator.
-=
The "subtract and assign" operator: subtracts the value of the right operand from the value of the left hand
operand and assign the result to left hand operand.
*=
The "multiply and assign" operator: multiplies the value of the right hand operand by the value of the left hand
operand and assign the result to left hand operand. .
/=
The "divide and assign" operator: divides the value of the right hand operand by the value of the left hand operand and
assign the result to left hand operand.
%=
The "modulus and assign" operator: calculates the modulus of the value of the right hand operand by the value of the
left hand operand and assign the result to left hand operand.
<<=
>>>=
&=
|=
^=
|| - the conditional-OR operators. The evaluation of <left-expr> && <right-expr> is equivalent to the following
pseudo-code:
{
boolean L = evaluate(<left-expr>);
if (L) {
return evaluate(<right-expr>);
} else {
short-circuit the evaluation of the 2nd operand expression return false;
{
boolean L = evaluate(<left-expr>);
if (!L) {
return evaluate(<right-expr>);
} else {
short-circuit the evaluation of the 2nd operand expression return true;
}
}
As the pseudo-code above illustrates, the behavior of the short-circuit operators are equivalent to using if / else
statements.
The following example shows the most common usage pattern for the && operator. Compare these two versions of a
method to test if a supplied Integer is zero.
The first version works in most cases, but if the value argument is null, then a NullPointerException will be thrown.
In the second version we have added a "guard" test. The value != null && value == 0 expression is evaluated by first
performing the value != null test. If the null test succeeds (i.e. it evaluates to true) then the value == 0 expression is
evaluated. If the null test fails, then the evaluation of value == 0 is skipped (short-circuited), and we don't get a
NullPointerException.
The following example shows how && can be used to avoid a relatively costly calculation:
In the first version, both operands of the | will always be evaluated, so the (expensive) isPrime method will be called
unnecessarily. The second version avoids the unnecessary call by using || instead of |.
`a < b` tests if the value of `a` is less than the value of `b`.
`a <= b` tests if the value of `a` is less than or equal to the value of `b`.
`a > b` tests if the value of `a` is greater than the value of `b`.
`a >= b` tests if the value of `a` is greater than or equal to the value of `b`.
Relational operators can be used to compare numbers with different types. For example:
int i = 1;
long l = 2;
if (i < l) {
System.out.println("i is smaller");
}
Relational operators can be used when either or both numbers are instances of boxed numeric types. For example:
You need to be careful with relational comparisons that involve floating point numbers:
Expressions that compute floating point numbers often incur rounding errors due to the fact that the
computer floating-point representations have limited precision.
When comparing an integer type and a floating point type, the conversion of the integer to floating point can also
lead to rounding errors.
Finally, Java does bit support the use of relational operators with any types other than the ones listed above. For
example, you cannot use these operators to compare strings, arrays of numbers, and so on.
These operators can be used operands with primitive and reference types, but the behavior is significantly
different. According to the JLS, there are actually three distinct sets of these operators:
However, in all cases, the result type of the == and != operators is boolean.
When one (or both) of the operands of an == or != operator is a primitive numeric type (byte, short, char, int, long,
float or double), the operator is a numeric comparison. The second operand must be either a primitive numeric type,
or a boxed numeric type.
Note: you need to be careful when using == and != to compare floating point values.
If both operands are boolean, or one is boolean and the other is Boolean, these operators the Boolean == and !=
operators. The behavior is as follows:
B A==BA!=B
false false true false
false true false true
true false false true
true true true false
There are two "pitfalls" that make it advisable to use == and != sparingly with truth values:
If you use == or != to compare two Boolean objects, then the Reference operators are used. This may give an
unexpected result; see Pitfall: using == to compare primitive wrappers objects such as Integer
The == operator can easily be mistyped as =. For most operand types, this mistake leads to a compilation
error. However, for boolean and Boolean operands the mistake leads to incorrect runtime behavior; see Pitfall -
Using '==' to test a boolean
If both operands are object references, the == and != operators test if the two operands refer to the same object. This
often not what you want. To test if two objects are equal by value, the .equals() method should be used instead.
s1.equals(s2); // true
Warning: using == and != to compare String values is incorrect in most cases; see
http://stackoverflow.com/documentation/java/4388/java-pitfalls/16290/using-to-compare-strings . A similar
problem applies to primitive wrapper types; see
http://stackoverflow.com/documentation/java/4388/java-pitfalls/8996/using-to-compare-primitive-wrappers-objects
-such-as-integer .
If either operand is NaN, then the result of == is false but the result of != is true. Indeed, the test x != x is true if
and only if the value of x is NaN.
This behavior is (to most programmers) unexpected. If you test if a NaN value is equal to itself, the answer is "No it
isn't!". In other words, == is not reflexive for NaN values.
However, this is not a Java "oddity", this behavior is specified in the IEEE 754 floating-point standards, and you will find
that it is implemented by most modern programming languages. (For more information, see
http://stackoverflow.com/a/1573715/139985 ... noting that this is written by someone who was "in the room when the
decisions were made"!)
Version ≥ Java SE 8
A lambda expression defines an anonymous function, or more correctly an instance of an anonymous class that
implements a functional interface.
(This example is included here for completeness. Refer to the Lambda Expressions topic for the full treatment.)
}
}
The visibility of the default constructor is the same as the visibility of the class. Thus a class defined package-
privately has a package-private default constructor
However, if you have non-default constructor, the compiler will not generate a default constructor for you. So these are
not equivalent:
Beware that the generated constructor performs no non-standard initialization. This means all fields of your class will
have their default value, unless they have an initializer.
public TestClass() {
testData = "Test"
}
}
class Parent {
private String name;
private int age;
This does not even compile, because name and age are private,
making them invisible even to the child class.
class Child extends Parent {
public Child() {
compiler implicitly calls super() here name =
"John";
age = 42;
}
}
class Parent {
private String name;
private int age;
public Parent(String tName, int tAge) {
name = tName;
age = tAge;
}
}
Note: Calls to another constructor (chaining) or the super constructor MUST be the first statement inside the
constructor.
If you call the super(...) constructor explicitly, a matching parent constructor must exist (that's straightforward, isn't it?).
class Parent{
public Parent(String tName, int tAge) {}
}
The class Parent has no default constructor, so, the compiler can't add super in the Child constructor. This code will not
compile. You must change the constructors to fit both sides, or write your own super call, like that:
A class can have multiple constructors with different signatures. To chain constructor calls (call a different
constructor of the same class when instantiating) use this().
public TestClass() {
this("Test"); // testData defaults to "Test"
}
}
Whenever it is invoked on the same object more than once during an execution of a Java application,
the hashCode method must consistently return the same integer, provided no information used in
equals comparisons on the object is modified. This integer need not remain consistent from one
execution of an application to another execution of the same application.
If two objects are equal according to the equals(Object) method, then calling the hashCode method
on each of the two objects must produce the same integer result.
It is not required that if two objects are unequal according to the equals(Object) method, then calling
the hashCode method on each of the two objects must produce distinct integer results. However, the
programmer should be aware that producing distinct integer results for unequal objects may improve
the performance of hash tables.
Hash codes are used in hash implementations such as HashMap, HashTable, and HashSet. The result of the hashCode
function determines the bucket in which an object will be put. These hash implementations are more efficient if the
provided hashCode implementation is good. An important property of good hashCode implementation is that the distribution
of the hashCode values is uniform. In other words, there is a small probability that numerous instances will be stored in the
same bucket.
An algorithm for computing a hash code value may be similar to the following:
this.field2 = field2;
this.field3 = field3;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) { return false;
In Java 1.2 and above, instead of developing an algorithm to compute a hash code, one can be generated using
java.util.Arrays#hashCode by supplying an Object or primitives array containing the field values:
@Override
public int hashCode() {
return Arrays.hashCode(new Object[] {field1, field2, field3});
}
Version ≥ Java SE 7
Java 1.7 introduced the java.util.Objects class which provides a convenience method, hash(Object... objects), that computes
a hash code based on the values of the objects supplied to it. This method works just like java.util.Arrays#hashCode.
@Override
public int hashCode() {
return Objects.hash(field1, field2, field3);
}
Note: this approach is inefficient, and produces garbage objects each time your custom hashCode() method is
called:
A temporary Object[] is created. (In the Objects.hash() version, the array is created by the "varargs"
mechanism.)
If any of the fields are primitive types, they must be boxed and that may create more temporary objects.
The array must be populated.
The array must iterated by the Arrays.hashCode or Objects.hash method.
The calls to Object.hashCode() that Arrays.hashCode or Objects.hash has to make (probably) cannot be inlined.
Since the calculation of an object's hash code can be expensive, it can be attractive to cache the hash code value
within the object the first time that it is calculated. For example
// Other methods
@Override
public int hashCode() {
int h = hash;
if (h == 0) {
h = Arrays.hashCode(array);
hash = h;
}
return h;
}
}
This approach trades off the cost of (repeatedly) calculating the hash code against the overhead of an extra field to
cache the hash code. Whether this pays off as a performance optimization will depend on how often a given object is
hashed (looked up) and other factors.
You will also notice that if the true hashcode of an ImmutableArray happens to be zero (one chance in 232), the cache
is ineffective.
Finally, this approach is much harder to implement correctly if the object we are hashing is mutable. However, there
are bigger concerns if hash codes change; see the contract above.
@Override
public String toString() {
return firstName + " " + lastName;
}
Here toString() from Object class is overridden in the User class to provide meaningful data regarding the object when
printing it.
When using println(), the object's toString() method is implicitly called. Therefore, these statements do the
If the toString() is not overridden in the above mentioned User class, System.out.println(user) may return User@659e0bfd or a
similar String with almost no useful information except the class name. This will be because the call will use the toString()
implementation of the base Java Object class which does not know anything about the User class's structure or business
rules. If you want to change this functionality in your class, simply override the method.
tests for reference equality (whether they are the same object)
.equals() tests for value equality (whether they are logically "equal")
equals() is a method used to compare two objects for equality. The default implementation of the equals() method in
the Object class returns true if and only if both references are pointing to the same instance. It therefore behaves
the same as comparison by ==.
Even though foo1 and foo2 are created with the same fields, they are pointing to two different objects in memory.
The default equals() implementation therefore evaluates to false.
@Override
@Override
public int hashCode() {
int hash = 1;
hash = 31 * hash + this.field1;
hash = 31 * hash + this.field2;
hash = 31 * hash + (field3 == null ? 0 : field3.hashCode());
return hash;
}
Here the overridden equals() method decides that the objects are equal if their fields are the same.
Notice that the hashCode() method was also overwritten. The contract for that method states that when two objects
are equal, their hash values must also be the same. That's why one must almost always override hashCode() and
equals() together.
Pay special attention to the argument type of the equals method. It is Object obj, not Foo obj. If you put the latter in your
method, that is not an override of the equals method.
When writing your own class, you will have to write similar logic when overriding equals() and hashCode(). Most IDEs
can automatically generate this for you.
An example of an equals() implementation can be found in the String class, which is part of the core Java API.
Rather than comparing pointers, the String class compares the content of the String.
Version ≥ Java SE 7
Java 1.7 introduced the java.util.Objects class which provides a convenience method, equals, that compares two potentially
null references, so it can be used to simplify implementations of the equals method.
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) { return false;
Since the equals method can run against any object, one of the first things the method often does (after checking for
null) is to check if the class of the object being compared matches the current class.
@Override
public boolean equals(Object obj) {
//...check for null
if (getClass() != obj.getClass()) {
return false;
}
//...compare fields
}
This is typically done as above by comparing the class objects. However, that can fail in a few special cases which
may not be obvious. For example, some frameworks generate dynamic proxies of classes and these dynamic proxies
are actually a different class. Here is an example using JPA.
One mechanism to work around that limitation is to compare classes using instanceof
@Override
public final boolean equals(Object obj) {
if (!(obj instanceof Foo)) {
return false;
}
//...compare fields
}
However, there are a few pitfalls that must be avoided when using instanceof. Since Foo could potentially have other
subclasses and those subclasses might override equals() you could get into a case where a Foo is equal to a FooSubclass
but the FooSubclass is not equal to Foo.
This violates the properties of symmetry and transitivity and thus is an invalid implementation of the equals() method.
As a result, when using instanceof, a good practice is to make the equals() method final (as in the above example).
This will ensure that no subclass overrides equals() and violates key assumptions.
package com.example.examples.object;
import java.util.concurrent.atomic.AtomicBoolean;
public static void main(String[] args) throws InterruptedException { final Object obj = new
Object();
AtomicBoolean aHasFinishedWaiting = new AtomicBoolean(false);
}
System.out.println("A3: Thread A has finished waiting. "
"Guaranteed to happen after B3");
} catch (InterruptedException e) {
System.out.println("Thread A was interrupted while waiting");
} finally {
aHasFinishedWaiting.set(true);
}
}
};
System.out.println("B2: Thread B is about to wait for 10 seconds"); for (int i = 0; i < 10;
i++) {
try {
Thread.sleep(1000); // sleep for 1 second
} catch (InterruptedException e) {
System.err.println("Thread B was interrupted from waiting");
}
}
while (!aHasFinishedWaiting.get()) {
synchronized (obj) {
notify ONE thread which has called obj.wait() obj.notify();
}
}
}
};
threadA.start();
threadB.start();
threadA.join();
threadB.join();
this.specificUserID = specificUserID;
}
}
The getClass() method will return the most specific class type, which is why when getClass() is called on
anotherSpecificUser, the return value is class SpecificUser because that is lower down the inheritance tree than User.
The actual static type returned by a call to getClass is Class<? extends T> where T is the static type of the object on
which getClass is called.
For the method to be used all classes calling the method must implement the Cloneable interface.
The Cloneable interface itself is just a tag interface used to change the behaviour of the native clone() method which
checks if the calling objects class implements Cloneable. If the caller does not implement this interface a
CloneNotSupportedException will be thrown.
The Object class itself does not implement this interface so a CloneNotSupportedException will be thrown if the calling
object is of class Object.
For a clone to be correct it should be independent of the object it is being cloned from, therefore it may be necessary to
modify the object before it gets returned. This means to essentially create a "deep copy" by also copying any of the
mutable objects that make up the internal structure of the object being cloned. If this is not implemented correctly the
cloned object will not be independent and have the same references to the mutable objects as the object that it was
cloned from. This would result in inconsistent behaviour as any changes to those in one would affect the other.
The fields y and z refer to a mutable objects; clone them recursively. if (this.y != null) {
} catch (CloneNotSupportedException e) {
in case any of the cloned mutable fields do not implement Cloneable throw new
AssertionError(e);
}
}
}
If you do not specify the call to super() in a constructor the compiler will put it in for you.
public MyClass() {
super();
}
}
public MyClass() {
// empty
}
}
It is possible to call other constructors as the first instruction of a constructor. As both the explicit call to a super
constructor and the call to another constructor have to be both first instructions, they are mutually exclusive.
doSomethingWith(size);
this(initialValues.size());
addInitialValues(initialValues);
}
}
Calling new MyClass(Arrays.asList("a", "b", "c")) will call the second constructor with the List-argument, which will in
turn delegate to the first constructor (which will delegate implicitly to super()) and then call addInitialValues(int size)
with the second size of the list. This is used to reduce code duplication where multiple constructors need to do the
same work.
Given the example above, one can either call new MyClass("argument") or new MyClass("argument", 0). In other words, much
like method overloading, you just call the constructor with the parameters that are necessary for your chosen constructor.
Nothing more than would happen in a sub-class that has a default empty constructor (minus the call to super()).
The default empty constructor can be explicitly defined but if not the compiler will put it in for you as long as no other
constructors are already defined.
The actual creation of objects is down to the JVM. Every constructor in Java appears as a special method named
<init> which is responsible for instance initializing. This <init> method is supplied by the compiler and because <init> is
not a valid identifier in Java, it cannot be used directly in the language.
The JVM will invoke the <init> method using the invokespecial instruction and can only be invoked on
uninitialized class instances.
For more information take a look at the JVM specification and the Java Language Specification:
According to the doc, this method gets called by the garbage collector on an object when garbage
collection determines that there are no more references to the object.
But there are no guarantees that finalize() method would gets called if the object is still reachable or no Garbage
Collectors run when the object become eligible. That's why it's better not rely on this method.
In Java core libraries some usage examples could be found, for instance in FileInputStream.java:
In this case it's the last chance to close the resource if that resource has not been closed before.
Generally it's considered bad practice to use finalize() method in applications of any kind and should be avoided.
Finalizers are not meant for freeing resources (e.g., closing files). The garbage collector gets called when (if!) the
system runs low on heap space. You can't rely on it to be called when the system is running low on file handles or, for
any other reason.
The intended use-case for finalizers is for an object that is about to be reclaimed to notify some other object about its
impending doom. A better mechanism now exists for that purpose---the java.lang.ref.WeakReference<T> class. If you think
you need write a finalize() method, then you should look into whether you can solve the same problem using
WeakReference instead. If that won't solve your problem, then you may need to re-think your design on a deeper level.
For further reading here is an Item about finalize() method from "Effective Java" book by Joshua Bloch.
An annotation is a marker which associates information with a program construct, but has no effect at run
time.
Annotations may appear before types or declarations. It is possible for them to appear in a place where they could apply
to both a type or a declaration.
What exactly an annotation applies to is governed by the "meta-annotation" @Target. See "Defining annotation
types" for more information.
Annotations are used for a multitude of purposes. Frameworks like Spring and Spring-MVC make use of
annotations to define where Dependencies should be injected or where requests should be routed.
Other frameworks use annotations for code-generation. Lombok and JPA are prime examples, that use annotations to
generate Java (and SQL) code.
@interface MyAnnotation {
String param1();
boolean param2();
int[] param3(); // array parameter
}
Default values
@interface MyAnnotation {
String param1() default "someValue";
boolean param2() default true;
int[] param3() default {};
}
Meta-Annotations
Meta-annotations are annotations that can be applied to annotation types. Special predefined meta-annotation define
how annotation types can be used.
The @Target meta-annotation restricts the types the annotation can be applied to.
@Target(ElementType.METHOD)
@interface MyAnnotation {
// this annotation can only be applied to methods
}
Multiple values can be added using array notation, e.g. @Target({ElementType.FIELD, ElementType.TYPE})
Available Values
ElementType target example usage on target element
@Retention(RetentionPolicy.RUNTIME) terface
ANNOTATION_TYPE annotation types
MyAnnotation
CONSTRUCTOR constructors @MyAnnotation lic MyClass() {}
FIELD fields, enum constants @XmlAttribute vate int count;
for (@LoopVariable int i = 0; i < 100; i++) {
variable declarations inside @Unused
LOCAL_VARIABLE methods String resultVariable;
}
package (in package-
PACKAGE @Deprecated kage very.old;
info.java )
The @Retention meta-annotation defines the annotation visibility during the applications compilation process or
execution. By default, annotations are included in .class files, but are not visible at runtime. To make an annotation
accessible at runtime, RetentionPolicy.RUNTIME has to be set on that annotation.
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
// this annotation can be accessed with reflections at runtime
}
Available values
RetentionPolicy Effect
CLASS The annotation is available in the .class file, but not at runtime
RUNTIME The annotation is available at runtime and can be accessed via reflection
The annotation is available at compile time, but not added to the .class files. The annotation can be
SOURCE
used e.g. by an annotation processor.
@Documented
The @Documented meta-annotation is used to mark annotations whose usage should be documented by API
documentation generators like javadoc. It has no values. With @Documented, all classes that use the annotation will list
it on their generated documentation page. Without @Documented, it's not possible to see which classes use the
@Inherited
The @Inherited meta-annotation is relevant to annotations that are applied to classes. It has no values. Marking an
annotation as @Inherited alters the way that annotation querying works.
For a non-inherited annotation, the query only examines the class being examined.
For an inherited annotation, the query will also check the super-class chain (recursively) until an instance of the
annotation is found.
Note that only the super-classes are queried: any annotations attached to interfaces in the classes hierarchy will be
ignored.
@Repeatable
The @Repeatable meta-annotation was added in Java 8. It indicates that multiple instances of the annotation can be
attached to the annotation's target. This meta-annotation has no values.
@interface MyDefaultAnnotation {
@Retention(RetentionPolicy.RUNTIME)
@interface MyRuntimeVisibleAnnotation {
@MyDefaultAnnotation
static class RuntimeCheck1 {
}
@MyRuntimeVisibleAnnotation
static class RuntimeCheck2 {
}
@Override
This annotation applies to a method and says that this method must override a superclass' method or implement an
abstract superclass' method definition. If this annotation is used with any other kind of method, the compiler will throw an
error.
Concrete superclass
Abstract class
class Logger1 {
public void log(String logString) {
System.out.prinln(logString);
}
}
class Logger2 {
This will throw compile-time error. Logger2 is not a subclass of Logger1.
log method is not overriding anything
@Override
public void log(String logString) {
System.out.println("Log 2" + logString);
}
}
The main purpose is to catch mistyping, where you think you are overriding a method, but are actually defining a new
one.
class Vehicle {
In Java 5, it meant that the annotated method had to override a non-abstract method declared in the
superclass chain.
From Java 6 onward, it is also satisfied if the annotated method implements an abstract method declared in the
classes superclass / interface hierarchy.
(This can occasionally cause problems when back-porting code to Java 5.)
@Deprecated
This marks the method as deprecated. There can be several reasons for this:
The specific reason for deprecation can usually be found in the documentation of the API.
The annotation will cause the compiler to emit an error if you use it. IDEs may also highlight this method somehow as
deprecated
class ComplexAlgorithm {
@Deprecated
public void oldSlowUnthreadSafeMethod() {
// stuff here
}
@SuppressWarnings
In almost all cases, when the compiler emits a warning, the most appropriate action is to fix the cause. In some
instances (Generics code using untype-safe pre-generics code, for example) this may not be possible and it's better to
suppress those warnings that you expect and cannot fix, so you can more clearly see unexpected warnings.
@SuppressWarnings("deprecation")
public class RiddledWithWarnings {
// several methods calling deprecated code here
}
@SuppressWarning("finally")
public boolean checkData() {
// method calling return from within finally block
}
It is better to limit the scope of the annotation as much as possible, to prevent unexpected warnings also being
suppressed. For example, confining the scope of the annotation to a single-line:
The warnings supported by this annotation may vary from compiler to compiler. Only the unchecked and
deprecation warnings are specifically mentioned in the JLS. Unrecognized warning types will be ignored.
@SafeVarargs
Because of type erasure, void method(T... t) will be converted to void method(Object[] t) meaning that the compiler is not
always able to verify that the use of varargs is type-safe. For instance:
There are instances where the use is safe, in which case you can annotate the method with the SafeVarargs
annotation to suppress the warning. This obviously hides the warning if your use is unsafe too.
@FunctionalInterface
This is an optional annotation used to mark a FunctionalInterface. It will cause the compiler to complain if it does not
conform to the FunctionalInterface spec (has a single abstract method)
@FunctionalInterface
public interface ITrade {
public boolean check(Trade t);
}
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
The annotation
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface Setter {
}
The annotation processor
The SetterProcessor class is used by the compiler to process the annotations. It checks, if the methods annotated with the
@Setter annotation are public, non-static methods with a name starting with set and having a uppercase letter as 4th
letter. If one of these conditions isn't met, a error is written to the Messager. The compiler writes this to stderr, but other
tools could use this information differently. E.g. the NetBeans IDE allows the user specify annotation processors that are
used to display error messages in the editor.
package annotation.processor;
import annotation.Setter;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor; import
javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion; import
javax.lang.model.element.Element; import
javax.lang.model.element.ElementKind; import
javax.lang.model.element.ExecutableElement; import
javax.lang.model.element.Modifier; import
javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes({"annotation.Setter"})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class SetterProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { // get elements
annotated with the @Setter annotation
Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(Setter.class);
don't claim annotations to allow other processors to process them return false;
@Override
public void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
}
Packaging
To be applied by the compiler, the annotation processor needs to be made available to the SPI (see ServiceLoader).
To do this a text file META-INF/services/javax.annotation.processing.Processor needs to be added to the jar file containing
the annotation processor and the annotation in addition to the other files. The file needs to include the fully qualified
name of the annotation processor, i.e. it should look like this
annotation.processor.SetterProcessor
The following class is example class in the default package with the annotations being applied to the correct
elements according to the retention policy. However only the annotation processor only considers the second
method a valid annotation target.
import annotation.Setter;
@Setter
private void setValue(String value) {}
@Setter
public void setString(String value) {}
@Setter
public static void main(String[] args) {}
}
Using the annotation processor with javac
If the annotation processor is discovered using the SPI, it is automatically used to process annotated elements. E.g.
compiling the AnnotationProcessorTest class using
This could be prevented by specifying the -proc:none option for javac. You could also forgo the usual compilation
by specifying -proc:only instead.
IDE integration
Netbeans
Annotation processors can be used in the NetBeans editor. To do this the annotation processor needs to be
specified in the project settings:
add check marks for Enable Annotation Processing and Enable Annotation Processing in Editor
in the popup that appears enter the fully qualified class name of the annotation processor and click Ok.
Result
// Author.java
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
String value();
}
// Authors.java
@Retention(RetentionPolicy.RUNTIME)
public @interface Authors {
Author[] value();
}
Test.java
@Authors({
@Author("Mary"),
@Author("Sam")
})
public class Test {
public static void main(String[] args) {
Author[] authors = Test.class.getAnnotation(Authors.class).value(); for (Author author :
authors) {
System.out.println(author.value());
Output:
Mary
Sam
}
}
}
Version ≥ Java SE 8
Java 8 provides a cleaner, more transparent way of using container annotations, using the @Repeatable annotation.
First we add this to the Author class:
@Repeatable(Authors.class)
This tells Java to treat multiple @Author annotations as though they were surrounded by the @Authors container. We can
also use Class.getAnnotationsByType() to access the @Author array by its own class, instead of through its
@Author("Mary")
@Author("Sam")
public class Test {
public static void main(String[] args) {
Author[] authors = Test.class.getAnnotationsByType(Author.class); for (Author author :
authors) {
System.out.println(author.value());
Output:
Mary
Sam
}
}
}
Example
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface InheritedAnnotationType {
}
and
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface UninheritedAnnotationType {
}
@UninheritedAnnotationType
class A {
}
@InheritedAnnotationType
class B extends A {
}
class C extends B {
}
System.out.println(new A().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println(new B().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println(new C().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println("_________________________________");
System.out.println(new A().getClass().getAnnotation(UninheritedAnnotationType.class));
will print a result similar to this (depending on the packages of the annotation):
null
@InheritedAnnotationType()
@InheritedAnnotationType()
_________________________________
@UninheritedAnnotationType()
null
null
Note that annotations can only be inherited from classes, not interfaces.
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
String key() default "foo";
String value() default "bar";
}
class AnnotationExample {
Put the Annotation on the method, but leave the defaults @MyAnnotation
example.testDefaults();
example.testValues();
} catch( Exception e ) {
// Shouldn't throw any Exceptions
System.err.println("Exception [" + e.getClass().getName() + "] - " + e.getMessage()); e.printStackTrace(System.err);
}
}
}
foo = bar
baz = buzz
The receiver parameter is an optional syntactic device for an instance method or an inner class's
constructor. For an instance method, the receiver parameter represents the object for which the method
is invoked. For an inner class's constructor, the receiver parameter represents the immediately enclosing
instance of the newly constructed object. Either way, the receiver parameter exists solely to allow the type
of the represented object to be denoted in source code, so that the type may be annotated. The receiver
parameter is not a formal parameter; more precisely, it is not a declaration of any kind of variable
(§4.12.3), it is never bound to any value passed as an argument in a method invocation expression or
qualified class instance creation expression, and it has no effect whatsoever at run time.
The following example illustrates the syntax for both kinds of receiver parameter:
The sole purpose of receiver parameters is to allow you to add annotations. For example, you might have a custom
annotation @IsOpen whose purpose is to assert that a Closeable object has not been closed when a method is called. For
example:
At one level, the @IsOpen annotation on this could simply serve as documentation. However, we could potentially do
more. For example:
An annotation processor could insert a runtime check that this is not in closed state when update is called. A
code checker could perform a static code analysis to find cases where this could be closed when update is called.
The value parameter is an array of Strings. You can set multiple values by using a notation similar to Array
initializers:
@SuppressWarnings({"unused"})
@SuppressWarnings({"unused", "javadoc"})
If you only need to set a single value, the brackets can be omitted:
@SuppressWarnings("unused")
By having an immutable object, one can ensure that all threads that are looking at the object will be seeing the
same state, as the state of an immutable object will not change.
Don't provide "setter" methods - methods that modify fields or objects referred to by fields.
Make all fields final and private.
Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more
sophisticated approach is to make the constructor private and construct instances in factory methods.
If the instance fields include references to mutable objects, don't allow those objects to be changed:
Don't provide methods that modify the mutable objects.
Don't share references to the mutable objects. Never store references to external, mutable objects passed to the
constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your
internal mutable objects when necessary to avoid returning the originals in your methods.
class Point {
private int x, y;
//...
One way to deal with this is to create an immutable wrapper for the mutable type. Here is a simple wrapper for an array
of integers
This class works by using defensive copying to isolate the mutable state (the int[]) from any code that might mutate it:
The constructor uses clone() to create a distinct copy of the parameter array. If the caller of the constructor
subsequent changed the parameter array, it would not affect the state of the ImmutableIntArray.
The getValue() method also uses clone() to create the array that is returned. If the caller were to change the result
array, it would not affect the state of the ImmutableIntArray.
We could also add methods to ImmutableIntArray to perform read-only operations on the wrapped array; e.g. get its
length, get the value at a particular index, and so on.
Note that an immutable wrapper type implemented this way is not type compatible with the original type. You
cannot simply substitute the former for the latter.
A variation on this is to declare the constructor as private and provide a public static factory method instead.
Immutability does not prevent object from being nullable; e.g. null can be assigned to a String variable. If an
immutable classes properties are declared as final, instances are inherently thread-safe. This makes immutable
classes a good building block for implementing multi-threaded applications.
public final class Person { // example of a bad immutability private final String
name;
private final String surname;
public Person(String name) {
this.name = name;
}
public String getName() { return name;}
public String getSurname() { return surname;}
public void setSurname(String surname) { this.surname = surname); }
}
To fix it, simply delete setSurname() and refactor the constructor as follows:
The following snippet shows that the above class is not immutable:
import java.util.List;
import java.util.ArrayList;
public final class Names {
private final List<String> names;
public Names(List<String> names) {
this.names = new ArrayList<String>(names);
}
public List<String> getNames() {
return names;
}
public int size() {
return names.size();
}
}
Names class seems immutable at the first sight, but it is not as the following code shows:
This happened because a change to the reference List returned by getNames() can modify the actual list of Names.
To fix this, simply avoid returning references that reference class's mutable objects either by making defensive
copies, as follows:
or by designing getters in way that only other immutable objects and primitives are returned, as follows:
Injecting constructor with object(s) that can be modified outside the immutable class
This is a variation of the previous flaw. Take a look at the following class:
import java.util.List;
public final class NewNames {
private final List<String> names;
public Names(List<String> names) {
this.names = names;
}
public String getName(int index) {
return names.get(index);
}
public int size() {
return names.size();
}
}
As Names class before, also NewNames class seems immutable at the first sight, but it is not, in fact the following
snippet proves the contrary:
To fix this, as in the previous flaw, simply make defensive copies of the object without assigning it directly to the
immutable class, i.e. constructor can be changed as follows:
Person class seems immutable at the first sight, but suppose a new subclass of Person is defined:
now Person (im)mutability can be exploited through polymorphism by using the new subclass:
To fix this, either mark the class as final so it cannot be extended or declare all of its constructor(s) as private.
class SomeClass {
private int variable;
System.out.println(sc.variable);
public Test(){
}
}
Now let's try to create an instance of the class. In this example, we can access number because it is public.
package javax.swing;
public abstract class JComponent extends Container … {
…
static boolean DEBUG_GRAPHICS_LOADED;
…
}
package javax.swing;
public class DebugGraphics extends Graphics {
…
static {
JComponent.DEBUG_GRAPHICS_LOADED = true;
}
…
}
As an example:
package com.stackexchange.docs;
public class MyClass{
protected int variable; //This is the variable that we are trying to access public MyClass(){
variable = 2;
};
}
Now we'll extend this class and try to access one of its protected members.
package some.other.pack;
import com.stackexchange.docs.MyClass;
public class SubClass extends MyClass{
public SubClass(){
super();
System.out.println(super.variable);
}
}
You would be also able to access a protected member without extending it if you are accessing it from the same
package.
There was once a private protected (both keywords at once) modifier that could be applied to methods or variables to
make them accessible from a subclass outside the package, but make them private to the classes in that package.
However, this was removed in Java 1.0's release.
public class X {
}
class Y {
}
}
Interface members always have public visibility, even if the public keyword is omitted. So both foo(), bar(), TEXT,
ANSWER, X, and Y have public visibility. However, access may still be limited by the containing interface - since
MyInterface has public visibility, its members may be accessed from anywhere, but if MyInterface had had package
visibility, its members would only have been accessible from within the same package.
This example uses generic class Param to take a single type parameter T, delimited by angle brackets (<>):
public T getValue() {
return value;
}
To instantiate this class, provide a type argument in place of T. For example, Integer:
The type argument can be any reference type, including arrays and other generic types:
Param<String[]> stringArrayParam;
Param<int[][]> int2dArrayParam;
Param<Param<Object>> objectNestedParam;
In Java SE 7 and later, the type argument can be replaced with an empty set of type arguments ( <>) called the
diamond:
Version ≥ Java SE 7
Param<Integer> integerParam = new Param<>();
Unlike other identifiers, type parameters have no naming constraints. However their names are commonly the first letter
of their purpose in upper case. (This is true even throughout the official JavaDocs.) Examples include T for "type", E for
"element" and K/V for "key"/"value".
public T getValue() {
return value;
}
AbstractParam is an abstract class declared with a type parameter of T. When extending this class, that type parameter
can be replaced by a type argument written inside <>, or the type parameter can remain unchanged. In the first and
second examples below, String and Integer replace the type parameter. In the third example, the type parameter remains
unchanged. The fourth example doesn't use generics at all, so it's similar to if the class had an Object parameter. The
compiler will warn about AbstractParam being a raw type, but it will compile the ObjectParam class. The fifth example has 2
type parameters (see "multiple type parameters" below), choosing the second parameter as the type parameter passed
to the superclass.
Notice that in the Email class, the T getValue() method acts as if it had a signature of String getValue(), and the void
setValue(T) method acts as if it was declared void setValue(String).
It is also possible to instantiate with anonymous inner class with an empty curly braces ( {}):
Java provides the ability to use more than one type parameter in a generic class or interface. Multiple type
parameters can be used in a class or interface by placing a comma-separated list of types between the angle
brackets. Example:
public T getFirstParam() {
return firstParam;
}
public S getSecondParam() {
return secondParam;
}
? extends T represents an upper bounded wildcard. The unknown type represents a type that must be a
subtype of T, or type T itself.
? super T represents a lower bounded wildcard. The unknown type represents a type that must be a
supertype of T, or type T itself.
Using extends or super is usually better because it makes your code more flexible (as in: allowing the use of
subtypes and supertypes), as you will see below.
class Shoe {}
class IPhone {}
interface Fruit {}
class Apple implements Fruit {}
class Banana implements Fruit {}
class GrannySmith extends Apple {}
Choosing the right T, ? super T or ? extends T is necessary to allow the use with subtypes. The compiler can then ensure
type safety; you should not need to cast (which is not type safe, and may cause programming errors) if you use them
properly.
(Producer has only write access, and Consumer has only read access)
Java 7 introduced the Diamond1 to remove some boiler-plate around generic class instantiation. With Java 7+ you can
write:
One limitation is for Anonymous Classes, where you still must provide the type parameter in the instantiation:
Although using the diamond with Anonymous Inner Classes is not supported in Java 7 and 8, it will be included as
a new feature in Java 9.
Footnote:
1 - Some people call the <> usage the "diamond operator". This is incorrect. The diamond does not behave as an
operator, and is not described or listed anywhere in the JLS or the (official) Java Tutorials as an operator. Indeed, <> is
not even a distinct Java token. Rather it is a < token followed by a > token, and it is legal (though bad style) to have
whitespace or comments between the two. The JLS and the Tutorials consistently refer to <> as "the diamond", and that
is therefore the correct term for it.
Notice that we don't have to pass an actual type argument to a generic method. The compiler infers the type
argument for us, based on the target type (e.g. the variable we assign the result to), or on the types of the actual
arguments. It will generally infer the most specific type argument that will make the call type-correct.
Sometimes, albeit rarely, it can be necessary to override this type inference with explicit type arguments:
void usage() {
consumeObjects(this.<Object>makeList("Jeff", "Atwood").stream());
}
It's necessary in this example because the compiler can't "look ahead" to see that Object is desired for T after calling
stream() and it would otherwise infer String based on the makeList arguments. Note that the Java language doesn't
support omitting the class or object on which the method is called ( this in the above example) when type arguments
are explicitly provided.
Example: we want to sort a list of numbers but Number doesn't implement Comparable.
public <T extends Number & Comparable<T>> void sortNumbers( List<T> n ) { Collections.sort(
n );
}
In this example T must extend Number and implement Comparable<T> which should fit all "normal" built-in number
implementations like Integer or BigDecimal but doesn't fit the more exotic ones like Striped64.
Since multiple inheritance is not allowed, you can use at most one class as a bound and it must be the first listed. For
example, <T extends Comparable<T> & Number> is not allowed because Comparable is an interface, and not a class.
Background
Generic parameterization on a class can be inspected by creating an anonymous inner class. This class will capture the
type information. In general this mechanism is referred to as super type tokens, which are detailed in Neal Gafter's
blog post.
Implementations
Guava's TypeToken
Spring's ParameterizedTypeReference
Jackson's TypeReference
Example usage
A Java compiler applies strong type checking to generic code and issues errors if the code violates type safety. Fixing
compile-time errors is easier than fixing runtime errors, which can be difficult to find.
Elimination of casts
By using generics, programmers can implement generic algorithms that work on collections of different types, can be
customized, and are type safe and easier to read.
The type T is erased. Since, at runtime, the JVM does not know what T originally was, it does not know which
constructor to call.
Workarounds
genericMethod(String.class);
Which throws exceptions, since there is no way to know if the passed class has an accessible default
constructor.
Version ≥ Java SE 8
genericMethod(String::new);
Without bounded generics, we cannot make a container class that is both generic and knows that each element is an
animal:
public AnimalContainer() {
col = new ArrayList<T>();
}
public BoundedAnimalContainer() {
col = new ArrayList<T>();
}
// Legal
AnimalContainer<Cat> a = new AnimalContainer<Cat>();
// Legal
AnimalContainer<String> a = new AnimalContainer<String>();
Assume we have a DataSeries<T> type (interface here), which defines a generic data series containing values of type T. It
is cumbersome to work with this type directly when we want to perform a lot of operations with e.g. double values, so we
define DoubleSeries extends DataSeries<Double>. Now assume, the original DataSeries<T> type has a method add(values)
which adds another series of the same length and returns a new one. How do we enforce the type of values and the type
of the return to be DoubleSeries rather than DataSeries<Double> in our derived class?
The problem can be solved by adding a generic type parameter referring back to and extending the type being
declared (applied to an interface here, but the same stands for classes):
Here T represents the data type the series holds, e.g. Double and DS the series itself. An inherited type (or types) can now
be easily implemented by substituting the above mentioned parameter by a corresponding derived type, thus, yielding a
concrete Double-based definition of the form:
At this moment even an IDE will implement the above interface with correct types in place, which, after a bit of
content filling may look like this:
DoubleSeriesImpl(Collection<Double> data) {
this.data = new ArrayList<>(data);
@Override
public DoubleSeries add(DoubleSeries values) {
List<Double> incoming = values != null ? values.data() : null; if (incoming == null ||
incoming.size() != data.size()) {
throw new IllegalArgumentException("bad series");
}
List<Double> newdata = new ArrayList<>(data.size()); for (int i = 0; i
< data.size(); i++) {
newdata.add(this.data.get(i) + incoming.get(i)); // beware autoboxing
}
return DoubleSeries.instance(newdata);
}
@Override
public List<Double> data() {
return Collections.unmodifiableList(data);
}
}
As you can see the add method is declared as DoubleSeries add(DoubleSeries values) and the compiler is happy.
Let's say you want to create a class whose Generic type should implement both Flushable and Closeable, you can write
Now, the ExampleClass only accepts as generic parameters, types which implement both Flushable and
Closeable.
ExampleClass<BufferedWriter> arg1; // Works because BufferedWriter implements both Flushable and Closeable
ExampleClass<Console> arg4; // Does NOT work because Console only implements Flushable
ExampleClass<ZipFile> arg5; // Does NOT work because ZipFile only implements Closeable
ExampleClass<Flushable> arg2; // Does NOT work because Closeable bound is not satisfied.
ExampleClass<Closeable> arg3; // Does NOT work because Flushable bound is not satisfied.
The class methods can choose to infer generic type arguments as either Closeable or Flushable.
/* You can even invoke the methods of any valid type directly. */
Note:
You cannot bind the generic parameter to either of the type using OR (|) clause. Only the AND (&) clause is supported.
Generic type can extends only one class and many interfaces. Class must be placed at the beginning of the list.
The method will compile with a warning. The code is actually more safe than it looks because the Java runtime will do a
cast when you use it:
Here, the cast will work when the returned type is any kind of List (i.e. returning List<String> would not trigger a
ClassCastException; you'd eventually get it when taking elements out of the list).
To work around this problem, you can create an API which uses typed keys:
With this approach, you can't put the wrong type into the map, so the result will always be correct (unless you
accidentally create two keys with the same name but different types).
Related:
Type-safe Map
Consider the following generic class Example declared with the formal parameter <T>:
class Example<T> {
This will always give a Compilation error because as soon as the compiler compiles the Java source into Java bytecode
it applies a process known as type erasure, which converts all generic code into non-generic code, making impossible to
distinguish among T types at runtime. The type used with instanceof has to be reifiable, which means that all information
about the type has to be available at runtime, and this is usually not the case for generic types.
The following class represents what two different classes of Example, Example<String> and Example<Number>, look like
after generics has stripped off by type erasure:
Since types are gone, it's not possible for the JVM to know which type is T.
You can always use unbounded wildcard (?) for specifying a type in the instanceof as follows:
The other side of the coin is that using an instance t of T with instanceof is legal, as shown in the following
example:
class Example<T> {
public boolean isTypeAString(T t) {
return t instanceof String; // No compilation error this time
}
}
because after the type erasure the class will look like the following:
Object obj1 = new String("foo"); // reference type Object, object type String Object obj2 = new
Integer(11); // reference type Object, object type Integer System.out.println(obj1 instanceof String); //
true
System.out.println(obj2 instanceof String); // false, it's an Integer, not a String
Choose a specific type to replace the formal type parameter <T> of MyGenericClass and implement it, as the
following example does:
This class only deals with String, and this means that using MyGenericInterface with different parameters (e.g.
Integer, Object etc.) won't compile, as the following snippet shows:
Declare another generic interface with the formal type parameter <T> which implements MyGenericInterface, as follows:
Note that a different formal type parameter may have been used, as follows:
This way is not recommended, since it is not 100% safe at runtime because it mixes up raw type (of the subclass) with
generics (of the interface) and it is also confusing. Modern Java compilers will raise a warning with this kind of
implementation, nevertheless the code - for compatibility reasons with older JVM (1.4 or earlier) - will compile.
All the ways listed above are also allowed when using a generic class as a supertype instead of a generic interface.
Class − A class can be defined as a template/blueprint that describes the behavior/state that the object of its type
support.
The advantage is that the same functionality is called with two different numbers of inputs. While invoking the
method according to the input we are passing, (In this case either one string value or two string values) the
corresponding method is executed.
Note: Methods cannot be overloaded by changing just the return type ( int method() is considered the same as String
method() and will throw a RuntimeException if attempted). If you change the return type you must also change the
parameters in order to overload.
Method Overloading
Method overloading (also known as static Polymorphism) is a way you can have two (or more) methods (functions) with
same name in a single class. Yes its as simple as that.
This way user can call the same method for area depending on the type of shape it has.
But the real question now is, how will java compiler will distinguish which method body is to be executed?
Well Java have made it clear that even though the method names (area() in our case) can be same but the
arguments method is taking should be different.
Overloaded methods must have different arguments list (quantity and types).
That being said we cannot add another method to calculate area of a square like this : public Double area(Long side)
because in this case, it will conflict with area method of circle and will cause ambiguity for java compiler.
Thank god, there are some relaxations while writing overloaded methods like
Well that's because which overloaded methods is to be invoked is decided at compile time, based on the actual
number of arguments and the compile-time types of the arguments.
Method Overriding
Well, method overriding (yes you guess it right, it is also known as dynamic polymorphism) is somewhat more
interesting and complex topic.
In method overriding we overwrite the method body provided by the parent class. Got it? No? Let's go through an
example.
So we have a class called Shape and it has method called area which will probably return the area of the shape.
Let's say now we have two classes called Circle and Rectangle.
See this annotation @Override, it is telling that this method is from parent
class Shape and is overridden here
@Override
public Double area(){
return 3.14 * radius * radius;
}
}
See this annotation @Override, it is telling that this method is from parent
class Shape and is overridden here
@Override
public Double area(){
return length * breadth;
}
So, now both of your children classes have updated method body provided by the parent ( Shape) class. Now
question is how to see the result? Well lets do it the old psvm way.
Drumbeats ......
//This should print 78.5
System.out.println("Shape of circle : "+circle.area());
}
}
Wow! isn't it great? Two objects of same type calling same methods and returning different values. My friend, that's the
power of dynamic polymorphism.
It is important to understand that constructors are different from methods in several ways:
Constructors can only take the modifiers public, private, and protected, and cannot be declared abstract, final, static,
or synchronized.
Constructors MUST be named the same as the class name. In the Hello example, the Hello object's
constructor name is the same as the class name.
The this keyword has an additional usage inside constructors. this.method(...) calls a method on the current instance,
while this(...) refers to another constructor in the current class with different signatures.
Constructors also can be called through inheritance using the keyword super.
public SuperManClass(){
// some implementation
}
// ... methods
}
static {
Set<String> set = new HashSet<>();
set.add("Hello");
set.add("World");
set.add("foo");
set.add("bar");
set.add("42");
WORDS = Collections.unmodifiableSet(set);
}
//Variables describing the characteristics of an individual car, varies per object private int milesPerGallon;
public Car(){
milesPerGallon = 0;
name = "";
color = "";
numGallonsInTank = 0;
}
name = carName;
color = carColor;
numGallonsInTank = gallonsInTank;
}
//check that car has enough gas to drive distanceInMiles if (miles <=
distanceInMiles){
numGallonsInTank = numGallonsInTank - (distanceInMiles / milesPerGallon)
System.out.println("Drove " + numGallonsInTank + " miles!");
} else {
System.out.println("Could not drive!");
}
}
Objects are instances of their class. So, the way you would create an object would be by calling the Car class in
one of two ways in your main class (main method in Java or onCreate in Android).
Option 1
Option 1 is where you essentially tell the program everything about the Car upon creation of the object. Changing any
property of the car would require calling one of the methods such as the repaintCar method. Example:
newCar.repaintCar("Blue");
Note: Make sure you pass the correct data type to the method. In the example above, you may also pass a variable to
the repaintCar method as long as the data type is correct`.
That was an example of changing properties of an object, receiving properties of an object would require using a
method from the Car class that has a return value (meaning a method that is not void). Example:
Option 1 is the best option when you have all the object's data at the time of creation.
Option 2
Option 2 gets the same effect but required more work to create an object correctly. I want to recall this Constructor in the
Car class:
Notice that you do not have to actually pass any parameters into the object to create it. This is very useful for when you
do not have all the aspects of the object but you need to use the parts that you do have. This sets generic data into each
of the instance variables of the object so that, if you call for a piece of data that does not exist, no errors
Note: Do not forget that you have to set the parts of the object later that you did not initialize it with. For example,
This is a common mistake amongst objects that are not initialized with all their data. Errors were avoided because there
is a Constructor that allows an empty Car object to be created with stand-in variables (public Car(){}), but no part of the
myCar was actually customized. Correct example of creating Car Object:
And, as a reminder, get an object's properties by calling a method in your main class. Example:
A class consists at a minimum of the class keyword, a name, and a body, which might be empty.
class ObjectMemberVsStaticMember {
void increment() {
staticCounter ++;
memberCounter++;
}
}
o1.increment();
o2.increment();
o2.increment();
System.out.println("ObjectMemberVsStaticMember.staticCounter = " +
ObjectMemberVsStaticMember.staticCounter);
o1 static counter 3
o1 member counter 1
o2 static counter 3
o2 member counter 2
ObjectMemberVsStaticMember.staticCounter = 3
Note: You should not call static members on objects, but on classes. While it does not make a difference for the JVM,
human readers will appreciate it.
static members are part of the class and exists only once per class. Non-static members exist on instances, there is an
independent copy for each instance. This also means that you need access to an object of that class to access its
members.
And the use thereof, which (notably) does not at all acknowledge the existence of the nested class.
//prints: 0, 1, 2, 3, 4,
for(int i = 0; i < 5; i++) {
System.out.print(s.pop() + ", ");
}
}
}
Or non-static:
At its core, static nested classes do not have a surrounding instance of the outer class, whereas non-static nested
classes do. This affects both where/when one is allowed to instantiate a nested class, and what instances of those
nested classes are allowed to access. Adding to the above example:
private StaticNestedClass() {
innerField = aField; //Illegal, can't access aField from static context
aMethod(); //Illegal, can't call aMethod from static context
}
private NestedClass() {
innerField = aField; //Legal
aMethod(); //Legal
Thus, your decision of static vs non-static mainly depends on whether or not you need to be able to directly access
fields and methods of the outer class, though it also has consequences for when and where you can construct the
nested class.
As a rule of thumb, make your nested classes static unless you need to access fields and methods of the outer class.
Similar to making your fields private unless you need them public, this decreases the visibility available to the nested
class (by not allowing access to an outer instance), reducing the likelihood of error.
public, as usual, gives unrestricted access to any scope able to access the type.
public int x = 5;
both protected and the default modifier (of nothing) behave as expected as well, the same as they do for non-nested
classes.
private, interestingly enough, does not restrict to the class it belongs to. Rather, it restricts to the compilation unit - the
.java file. This means that Outer classes have full access to Inner class fields and methods, even if they are marked
private.
private int x;
private void anInnerMethod() {}
}
The Inner Class itself can have a visibility other than public. By marking it private or another restricted access modifier,
other (external) classes will not be allowed to import and assign the type. They can still get references to objects of that
type, however.
Anonymous classes are typically used in situations where you need to be able to create a light-weight class to be
passed as a parameter. This is typically done with an interface. For example:
This anonymous class defines a Comparator<String> object (CASE_INSENSITIVE) that compares two strings ignoring
differences in case.
Other interfaces that are frequently implemented and instantiated using anonymous classes are Runnable and
Anonymous inner classes can also be based on classes. In this case, the anonymous class implicitly extends the
existing class. If the class being extended is abstract, then the anonymous class must implement all abstract
methods. It may also override non-abstract methods.
Constructors
An anonymous class cannot have an explicit constructor. Instead, an implicit constructor is defined that uses
super(...) to pass any parameters to a constructor in the class that is being extended. For example:
The implicit constructor for our anonymous subclass of SomeClass will call a constructor of SomeClass that matches the
call signature SomeClass(int, String). If no constructor is available, you will get a compilation error. Any exceptions that are
thrown by the matched constructor are also thrown by the implicit constructor.
Naturally, this does not work when extending an interface. When you create an anonymous class from an interface, the
classes superclass is java.lang.Object which only has a no-args constructor.
The inner class depends on the outside class and requires a reference to an instance of it. To create an instance of the
inner class, the new operator only needs to be called on an instance of the outer class.
class OuterClass {
class InnerClass {
}
}
class OutsideClass {
OuterClass.InnerClass createInner() {
return outer.new InnerClass();
}
}
A method-local inner class can be instantiated only within the method where the inner class is defined.
You can access fields and methods of the outer class directly.
But in case of name collision you can use the outer class reference.
// updating my counter
counter = OuterClass.this.counter;
}
}
}
With the Objects.nonNull method and Java8 Stream API, we can do the above in this way:
/**
Class which falls back to default implementation of {@link #printString()}
*/
public class WithDefault
implements Printable
{
}
/**
Custom implementation of {@link #printString()}
*/
public class OverrideDefault
implements Printable {
@Override
public void printString() {
System.out.println( "overridden implementation" );
}
}
new WithDefault().printString();
new OverrideDefault().printString();
default implementation
overridden implementation
For example, you have Swim interface that you published 20 years ago.
We did a great job, our interface is very popular, there are many implementation on that around the world and you don't
have control over their source code.
After 20 years, you've decided to add new functionality to the interface, but it looks like our interface is frozen
because it will break existing implementations.
Now all existing implementations of our interface can still work. But most importantly they can implement the newly
added method in their own time.
One of the biggest reasons for this change, and one of its biggest uses, is in the Java Collections framework. Oracle
could not add a foreach method to the existing Iterable interface without breaking all existing code which implemented
Iterable. By adding default methods, existing Iterable implementation will inherit the default implementation.
int getB();
@Override
public int getB() {
return 2;
}
}
System.out.println(new Sum().calculateSum());
Default methods could be used along with interface static methods as well:
System.out.println(new Sum().calculateSum());
public interface A {
default void foo() { System.out.println("A.foo"); }
}
public interface B {
default void foo() { System.out.println("B.foo"); }
Here are two interfaces declaring default method foo with the same signature.
If you will try to extend these both interfaces in the new interface you have to make choice of two, because Java
forces you to resolve this collision explicitly.
First, you can declare method foo with the same signature as abstract, which will override A and B behaviour.
And when you will implement ABExtendsAbstract in the class you will have to provide foo implementation:
Or second, you can provide a completely new default implementation. You also may reuse code of A and B foo
methods by Accessing overridden default methods from implementing class.
And when you will implement ABExtends in the class you will not have to provide foo implementation:
Will produce
AbstractSwimmer.backStroke
new FooSwimmer().backStroke();
Will produce
FooSwimmer.backStroke
package foo.bar
package foo.bar.baz
The above is fine because the two classes exist in different packages.
package foo.bar
public ExampleClass() {
exampleNumber = 3;
exampleString = "Test String";
}
//No getters or setters
}
package foo.bar
package baz.foo
Additional content can be added to a subclass. Doing so allows for additional functionality in the subclass without any
change to the base class or any other subclasses from that same base class:
public int x;
public SubClassWithField(int x) {
this.x = x; //Can access fields
}
}
private fields and methods still exist within the subclass, but are not accessible:
private int x = 5;
This is known as multiple inheritance, and while it is legal in some languages, Java does not permit it with classes.
As a result of this, every class has an unbranching ancestral chain of classes leading to Object, from which all
classes descend.
An abstract class cannot be instantiated. It can be sub-classed (extended) as long as the sub-class is either also
abstract, or implements all methods marked as abstract by super classes.
The class must be marked abstract, when it has at least one abstract method. An abstract method is a method that has
no implementation. Other methods can be declared within an abstract class that have implementation in order to provide
common code for any sub-classes.
However a class that extends Component, and provides an implementation for all of its abstract methods and can be
instantiated.
@Override
public void render() {
//render a button
}
}
@Override
public void render() {
//render a textbox
}
}
Instances of inheriting classes also can be cast as the parent class (normal inheritance) and they provide a
polymorphic effect when the abstract method is called.
Abstract classes and interfaces both provide a way to define method signatures while requiring the
extending/implementing class to provide the implementation.
There are two key differences between abstract classes and interfaces:
A class may only extend a single class, but may implement many interfaces.
An abstract class can contain instance (non-static) fields, but interfaces may only contain static fields. Version
< Java SE 8
Methods declared in interfaces could not contain implementations, so abstract classes were used when it was
useful to provide additional methods which implementations called the abstract methods.
Version ≥ Java SE 8
Java 8 allows interfaces to contain default methods, usually implemented using the other methods of the interface,
making interfaces and abstract classes equally powerful in this regard.
As a convenience java allows for instantiation of anonymous instances of subclasses of abstract classes, which
provide implementations for the abstract methods upon creating the new object. Using the above example this could
look like this:
When used in a class declaration, the final modifier prevents other classes from being declared that extend the class. A
final class is a "leaf" class in the inheritance class hierarchy.
Final classes can be combined with a private constructor to control or prevent the instantiation of a class. This can be
used to create a so-called "utility class" that only defines static members; i.e. constants and static methods.
Immutable classes should also be declared as final. (An immutable class is one whose instances cannot be changed
after they have been created; see the Immutable Objects topic. ) By doing this, you make it impossible to create a
mutable subclass of an immutable class. That would violate the Liskov Substitution Principle which requires that a
subtype should obey the "behavioral contract" of its supertypes.
From a practical perspective, declaring an immutable class to be final makes it easier to reason about program
behavior. It also addresses security concerns in the scenario where untrusted code is executed in a security sandbox.
(For instance, since String is declared as final, a trusted class does not need to worry that it might be tricked into
accepting mutable subclass, which the untrusted caller could then surreptitiously change.)
One disadvantage of final classes is that they do not work with some mocking frameworks such as Mockito.
Update: Mockito version 2 now support mocking of final classes.
Final methods
@Override
public void someMethod() { // Compiler error (overridden method is final)
}
}
Final methods are typically used when you want to restrict what a subclass can change in a class without forbidding
subclasses entirely.
The final modifier can also be applied to variables, but the meaning of final for variables is unrelated to
inheritance.
class A {...}
class B extends A {...}
This also applies when the type is an interface, where there doesn't need to any hierarchical relationship between the
objects:
interface Foo {
void bar();
}
Now the list contains objects that are not from the same class hierarchy.
Abstract classes create "is a" relations while interfaces provide "has a" capability.
System.out.println("Dog:"+dog);
System.out.println("Cat:"+cat);
dog.remember();
dog.protectOwner();
Learn dl = dog;
dl.learn();
cat.remember();
cat.protectOwner();
Climb c = cat;
c.climb();
Climb cm = man;
cm.climb();
Think t = man;
t.think();
Learn l = man;
l.learn();
Apply a = man;
a.apply();
}
}
interface Learn {
void learn();
}
interface Apply{
void apply();
}
output:
Dog:Dog:Jack:16
Cat:Cat:Joe:20
Dog can remember for 5 minutes
Dog will protect owner
Dog can learn:
Cat can remember for 16 hours
Cat won't protect owner
Cat can climb
Man :Ravindra:Age:40
I can climb:Man
I can think:Man
I can learn:Man
I can apply:Man
Key notes:
Animal is an abstract class with shared attributes: name and lifeExpectancy and abstract methods: remember()
and protectOwner(). Dog and Cat are Animals that have implemented the remember() and protectOwner()
methods.
Cat can climb() but Dog cannot. Dog can think() but Cat cannot. These specific capabilities are added to Cat and Dog by
implementation.
Man is not an Animal but he can Think , Learn, Apply, and Climb.
Man is neither a Cat nor a Dog but can have some of the capabilities of the latter two without extending Animal,
Cat, or Dog. This is done with Interfaces.
TL;DR:
Unrelated classes can have capabilities through interfaces, but related classes change the behaviour through extension
of base classes.
Refer to the Java documentation page to understand which one to use in a specific use case.
You expect that unrelated classes would implement your interface. For example, many unrelated objects can
implement the Serializable interface.
SubClass.sayHello();
//This will be different than the above statement's output, since it runs //A different method
SubClass.sayHello(true);
StaticOverride.sayHello();
System.out.println("StaticOverride's num: " + StaticOverride.num);
}
}
//Inherits the sayHello function, but does not override it public static void
sayHello(boolean test) {
System.out.println("Hey");
}
}
Hello
BaseClass's num: 5
Note that unlike normal inheritance, in static inheritance methods are not hidden. You can always call the base
sayHello method by using BaseClass.sayHello(). But classes do inherit static methods if no methods with the same
signature are found in the subclass. If two method's signatures vary, both methods can be run from the subclass,
even if the name is the same.
Not only the former can be applied to a wider choice of arguments, its results will be more compatible with code
provided by other developers that generally adhere to the concept of programming to an interface. However, the most
important reasons to use the former are:
most of the time the context, in which the result is used, does not and should not need that many details as the
concrete implementation provides;
adhering to an interface forces cleaner code and less hacks such as yet another public method gets added to a
class serving some specific scenario;
the code is more testable as interfaces are easily mockable;
finally, the concept helps even if only one implementation is expected (at least for testability).
So how can one easily apply the concept of programming to an interface when writing new code having in mind one
particular implementation? One option that we commonly use is a combination of the following patterns:
programming to an interface
factory
builder
The following example based on these principles is a simplified and truncated version of an RPC implementation
written for a number of different protocols:
The above interface is not supposed to be instantiated directly via a factory, instead we derive further more
Instances of RemoteInvoker for the use with AMQP can now be constructed as easy as (or more involved depending on
the builder):
Due to Java 8 permitting placing of static methods directly into interfaces, the intermediate factory has become
implicit in the above code replaced with AmqpInvoker.with(). In Java prior to version 8, the same effect can be
achieved with an inner Factory class:
The builder used above could look like this (although this is a simplification as the actual one permits defining of up to 15
parameters deviating from defaults). Note that the construct is not public, so it is specifically usable only from the above
AmqpInvoker interface:
Finally, the standard (and the only expected) implementation of this interface is defined as a package-local class to
enforce the use of the interface, the factory and the builder:
@Override
public <RQ, RS> CompletableFuture<RS> invoke(final RQ request, final Class<RS> respClass) {
...
}
}
Meanwhile, this pattern proved to be very efficient in developing all our new code not matter how simple or
complex the functionality is.
The following example demonstrates how ClassB overrides the functionality of ClassA by changing what gets sent out
through the printing method:
Example:
class ClassA {
public void printing() {
System.out.println("A");
}
}
Output:
class Car {
public int gearRatio = 8;
Casting an instance of a subclass to a base class as in: A a = b; is called widening and does not need a type-cast.
class Vehicle {
}
class Test {
The statement Vehicle vehicle = new Car(); is a valid Java statement. Every instance of Car is also a Vehicle.
Therefore, the assignment is legal without the need for an explicit type-cast.
On the other hand, Car c = vehicle; is not valid. The static type of the vehicle variable is Vehicle which means
that it could refer to an instance of Car, Truck,MotorCycle, or any other current or future subclass
ofVehicle. (Or indeed, an instance ofVehicleitself, since we did not declare it as anabstractclass.)
The assignment cannot be allowed, since that might lead tocarreferring to aTruck` instance.
The type-cast tells the compiler that we expect the value of vehicle to be a Car or a subclass of Car. If necessary,
compiler will insert code to perform a run-time type check. If the check fails, then a ClassCastException will be thrown
when the code is executed.
The Java compiler knows that an instance that is type compatible with Vehicle cannot ever be type compatible with
String. The type-cast could never succeed, and the JLS mandates that this gives in a compilation error.
class StaticMethodTest {
Static methods are bind to a class not to an instance and this method binding happens at compile time. Since in the first
call to staticMethod(), parent class reference p was used, Parent's version of staticMethod() is invoked. In second case, we
did cast p into Child class, Child's staticMethod() executed.
Strong Reference
Weak Reference
Soft Reference
Phantom Reference
1. Strong Reference
The variable holder is holding a strong reference to the object created. As long as this variable is live and holds this
value, the MyObject instance will not be collected by the garbage collector.
2. Weak Reference
When you do not want to keep an object longer, and you need to clear/free the memory allocated for an object as soon
as possible, this is the way to do so.
Simply, a weak reference is a reference that isn't strong enough to force an object to remain in memory. Weak
references allow you to leverage the garbage collector's ability to determine reachability for you, so you don't have to do
it yourself.
When you need the object you created, just use .get() method:
myObjectRef.get();
3. Soft Reference
Soft references are slightly stronger than weak references. You can create a soft referenced object as following:
They can hold onto the memory more strongly than the weak reference. If you have enough memory
supply/resources, garbage collector will not clean the soft references as enthusiastically as weak references.
System.out.println(myObjectRef.get()); // This may or may not print the reference address of the Object
4. Phantom Reference
This is the weakest referencing type. If you created an object reference using Phantom Reference, the get()
method will always return null!
The use of this referencing is that "Phantom reference objects, which are enqueued after the collector determines that
their referents may otherwise be reclaimed. Phantom references are most often used for scheduling pre-mortem
cleanup actions in a more flexible way than is possible with the Java finalization mechanism." - From Phantom
Reference Javadoc from Oracle.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
Using Scanner:
Version ≥ Java SE 5
System.out.println("Please type your name and press Enter");
import java.util.Scanner;
System.out.println("Please enter your first and your last name, on separate lines.");
There are two methods for obtaining Strings, next() and nextLine(). next() returns text up until the first space (also known
as a "token"), and nextLine() returns all text that the user inputted until pressing enter.
Scanner also provides utility methods for reading data types other than String. These include:
scanner.nextByte();
scanner.nextShort();
scanner.nextInt();
scanner.nextLong();
scanner.nextFloat();
scanner.nextDouble();
scanner.nextBigInteger();
Prefixing any of these methods with has (as in hasNextLine(), hasNextInt()) returns true if the stream has any more of the
request type. Note: These methods will crash the program if the input is not of the requested type (for example, typing
"a" for nextInt() ). You can use a try {} catch() {} to prevent this (see: Exceptions)
Using System.console:
Version ≥ Java SE 6
String name = System.console().readLine("Please type your name and press Enter%n");
Advantages:
Note: This will only work if the program is run from a real command line without redirecting the standard input and output
streams. It does not work when the program is run from within certain IDEs, such as Eclipse. For code that works within
IDEs and with stream redirection, see the other examples.
Output:
Using format strings with fixed size permits to print the strings in a table-like appearance with fixed size columns:
Output:
1 1 1
123 1234 1234
123 1234567 123456
123 12345678 123456
private static final String CMD_QUIT = "quit"; //string for exiting the program
private static final String CMD_HELLO = "hello"; //string for printing "Hello World!" on
the screen
private static final String CMD_ANSWER = "answer"; //string for printing 42 on the screen
try {
claimCli.start(); //calls the start function to do the work like console
}
catch (IOException e) {
e.printStackTrace(); //prints the exception log if it is failed to do get
the user
input or something like that
}
}
cmd = reader.readLine(); //takes input from user. user input should be started
with
"hello", "answer" or "quit"
String[] cmdArr = cmd.split(" ");
prints "Hello World!" on the screen if user input starts with "hello" private void hello(String[]
cmdArr) {
System.out.println("Hello World!");
}
Output:
APPLE
BANANA
ORANGE
PEAR
Create a Stream<String> containing a sequenced ordered Stream of fruit String elements using the static factory
method Stream.of(values).
The filter() operation retains only elements that match a given predicate (the elements that when tested by the
predicate return true). In this case, it retains the elements containing an "a". The predicate is given as a lambda
expression.
The map() operation transforms each element using a given function, called a mapper. In this case, each fruit String is
mapped to its uppercase String version using the method-reference String::toUppercase.
Note that the map() operation will return a stream with a different generic type if the mapping function
returns a type different to its input parameter. For example on a Stream<String> calling
.map(String::isEmpty) returns a Stream<Boolean>
4. The sorted() operation sorts the elements of the Stream according to their natural ordering
Finally, the forEach(action) operation performs an action which acts on each element of the Stream, passing it to a
Consumer. In the example, each element is simply being printed to the console. This operation is a terminal
operation, thus making it impossible to operate on it again.
Note that operations defined on the Stream are performed because of the terminal operation.
Without a terminal operation, the stream is not processed. Streams can not be reused. Once a
terminal operation is called, the Stream object becomes unusable.
Operations (as seen above) are chained together to form what can be seen as a query on the data.
Closing Streams
Note that a Stream generally does not have to be closed. It is only required to close streams that
operate on IO channels. Most Stream types don't operate on resources and therefore don't require
closing.
The Stream interface extends AutoCloseable. Streams can be closed by calling the close method or by using try-with-
resource statements.
An example use case where a Stream should be closed is when you create a Stream of lines from a file:
The Stream interface also declares the Stream.onClose() method which allows you to register Runnable handlers which will
be called when the stream is closed. An example use case is where code which produces a stream needs to know when
it is consumed to perform some cleanup.
The run handler will only execute if the close() method gets called, either explicitly or implicitly by a try-with-
resources statement.
Processing Order
In a sequential mode, the elements are processed in the order of the source of the Stream. If the Stream is ordered (such
as a SortedMap implementation or a List) the processing is guaranteed to match the ordering of the source. In other cases,
however, care should be taken not to depend on the ordering (see: is the Java HashMap keySet() iteration order
consistent?).
Example:
// sequential
long howManyOddNumbers = integerList.stream()
.filter(e -> (e % 2) == 1)
.count();
System.out.println(howManyOddNumbers); // Output: 2
Live on Ideone
Parallel mode allows the use of multiple threads on multiple cores but there is no guarantee of the order in which
elements are processed.
If multiple methods are called on a sequential Stream, not every method has to be invoked. For example, if a Stream is
filtered and the number of elements is reduced to one, a subsequent call to a method such as sort will not occur. This can
increase the performance of a sequential Stream — an optimization that is not possible with a parallel Stream.
Example:
// parallel
long howManyOddNumbersParallel = integerList.parallelStream()
.filter(e -> (e % 2) == 1)
.count();
System.out.println(howManyOddNumbersParallel); // Output: 2
Live on Ideone
While some actions can be performed on both Containers and Streams, they ultimately serve different purposes and
support different operations. Containers are more focused on how the elements are stored and how those elements can
be accessed efficiently. A Stream, on the other hand, doesn't provide direct access and manipulation to its elements; it is
more dedicated to the group of objects as a collective entity and performing operations on that entity as a whole. Stream
and Collection are separate high-level abstractions for these differing purposes.
In the following example, no terminal operation is added to the Stream, so the filter() operation will not be invoked
and no output will be produced because peek() is NOT a terminal operation.
Live on Ideone
This is a Stream sequence with a valid terminal operation, thus an output is produced.
Live on Ideone
Output:
2
4
6
8
After the terminal operation is performed, the Stream is consumed and cannot be reused.
Although a given stream object cannot be reused, it's easy to create a reusable Iterable that delegates to a stream
pipeline. This can be useful for returning a modified view of a live data set without having to collect results into a
temporary structure.
Output:
foo
bar