100% found this document useful (1 vote)
1K views1,225 pages

0882 Learning Java Language PDF

Uploaded by

Suman Pal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
1K views1,225 pages

0882 Learning Java Language PDF

Uploaded by

Suman Pal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1225

Java Language

#java
Table of Contents
About 1

Chapter 1: Getting started with Java Language 2

Remarks 2

Java Editions and Versions 2

Installing Java 3

Compiling and running Java programs 3

What's next? 3

Testing 3

Other 3

Versions 4

Examples 4

Creating Your First Java Program 4

A closer look at the Hello World program 6

Chapter 2: 2D Graphics in Java 11

Introduction 11

Examples 11

Example 1: Draw and Fill a Rectangle Using Java 11

Example 2: Drawing and Filling Oval 13

Chapter 3: Alternative Collections 14

Remarks 14

Examples 14

Apache HashBag, Guava HashMultiset and Eclipse HashBag 14

1. Using SynchronizedSortedBag from Apache: 14

2. Using TreeBag from Eclipse(GC): 15

3. Using LinkedHashMultiset from Guava: 15

More examples: 16

Multimap in Guava, Apache and Eclipse Collections 16

Nore examples: 19

Compare operation with collections - Create collections 19

Compare operation with collections - Create collections 19


Chapter 4: Annotations 25

Introduction 25

Syntax 25

Remarks 25

Parameter types 25

Examples 25

Built-in annotations 25

Runtime annotation checks via reflection 29

Defining annotation types 29

Default values 30

Meta-Annotations 30

@Target 30

Available Values 30

@Retention 31

Available values 32

@Documented 32

@Inherited 32

@Repeatable 32

Getting Annotation values at run-time 32

Repeating Annotations 33

Inherited Annotations 35

Example 35

Compile time processing using annotation processor 36

The annotation 36

The annotation processor 36

Packaging 38

Example annotated class 38

Using the annotation processor with javac 38

IDE integration 39

Netbeans 39

Result 39
The idea behind Annotations 40

Annotations for 'this' and receiver parameters 40

Add multiple annotation values 41

Chapter 5: Apache Commons Lang 42

Examples 42

Implement equals() method 42

Implement hashCode() method 42

Implement toString() method 43

Chapter 6: AppDynamics and TIBCO BusinessWorks Instrumentation for Easy Integration 45

Introduction 45

Examples 45

Example of Instrumentation of all BW Applications in a Single Step for Appdynamics 45

*** Common variables. Modify these only. *** 45

Chapter 7: Applets 47

Introduction 47

Remarks 47

Examples 47

Minimal Applet 47

Creating a GUI 48

Open links from within the applet 49

Loading images, audio and other resources 49

Load and show an image 49

Load and play an audio file 50

Load and display a text file 50

Chapter 8: Arrays 52

Introduction 52

Syntax 52

Parameters 52

Examples 52

Creating and Initializing Arrays 52

Basic cases 52
Arrays, Collections, and Streams 53

Intro 53

Creating and initializing primitive type arrays 55

Creating and initializing multi-dimensional arrays 56

Multidimensional array representation in Java 57

Creating and initializing reference type arrays 57

Creating and initializing generic type arrays 58

Filling an array after initialization 58

Separate declaration and initialization of arrays 59

Arrays may not be re-initialized with array initializer shortcut syntax 59

Creating an Array from a Collection 60

Arrays to a String 61

Creating a List from an Array 62

Important notes related to using Arrays.asList() method 63

Multidimensional and Jagged Arrays 64

How Multidimensional Arrays are represented in Java 65

ArrayIndexOutOfBoundsException 66

Getting the Length of an Array 67

Comparing arrays for equality 67

Arrays to Stream 68

Iterating over arrays 68

Copying arrays 71

for loop 71

Object.clone() 71

Arrays.copyOf() 72

System.arraycopy() 72

Arrays.copyOfRange() 72

Casting Arrays 73

Remove an element from an array 73

Using ArrayList 73
Using System.arraycopy 74

Using Apache Commons Lang 74

Array Covariance 74

How do you change the size of an array? 75

A better alternatives to array resizing 76

Finding an element in an array 76

Using Arrays.binarySearch (for sorted arrays only) 76

Using a Arrays.asList (for non-primitive arrays only) 76

Using a Stream 77

Linear search using a loop 77

Linear search using 3rd-party libraries such as org.apache.commons 77

Testing if an array contains an element 77

Sorting arrays 78

Converting arrays between primitives and boxed types 79

Chapter 9: Asserting 81

Syntax 81

Parameters 81

Remarks 81

Examples 81

Checking arithmetic with assert 81

Chapter 10: Atomic Types 82

Introduction 82

Parameters 82

Remarks 82

Examples 82

Creating Atomic Types 82

Motivation for Atomic Types 83

How does one implement Atomic Types? 84

How do Atomic Types work? 85

Chapter 11: Audio 87

Remarks 87
Examples 87

Play an Audio file Looped 87

Play a MIDI file 87

Bare metal sound 89

Basic audio output 89

Chapter 12: Autoboxing 91

Introduction 91

Remarks 91

Examples 91

Using int and Integer interchangeably 91

Using Boolean in if statement 92

Auto-unboxing may lead to NullPointerException 93

Memory and Computational Overhead of Autoboxing 93

Different Cases When Integer and int can be used interchangeably 94

Chapter 13: Basic Control Structures 96

Remarks 96

Examples 96

If / Else If / Else Control 96

For Loops 97

While Loops 98

do...while Loop 98

For Each 98

If / Else 99

Switch statement 100

Ternary Operator 102

Break 102

Try ... Catch ... Finally 102

Nested break / continue 103

Continue Statement in Java 104

Chapter 14: Benchmarks 105

Introduction 105

Examples 105
Simple JMH example 105

Chapter 15: BigDecimal 108

Introduction 108

Examples 108

BigDecimal objects are immutable 108

Comparing BigDecimals 108

Mathematical operations with BigDecimal 108

1.Addition 108

2.Subtraction 109

3.Multiplication 109

4.Division 109

5.Remainder or Modulus 110

6.Power 110

7.Max 111

8.Min 111

9.Move Point To Left 111

10.Move Point To Right 111

Using BigDecimal instead of float 112

BigDecimal.valueOf() 113

Initialization of BigDecimals with value zero, one or ten 113

Chapter 16: BigInteger 114

Introduction 114

Syntax 114

Remarks 114

Examples 115

Initialization 115

Comparing BigIntegers 116

BigInteger Mathematical Operations Examples 117

Binary Logic Operations on BigInteger 119

Generating random BigIntegers 120

Chapter 17: Bit Manipulation 122


Remarks 122

Examples 122

Packing / unpacking values as bit fragments 122

Checking, setting, clearing, and toggling individual bits. Using long as bit mask 123

Expressing the power of 2 123

Checking if a number is a power of 2 124

java.util.BitSet class 126

Signed vs unsigned shift 126

Chapter 18: BufferedWriter 128

Syntax 128

Remarks 128

Examples 128

Write a line of text to File 128

Chapter 19: ByteBuffer 130

Introduction 130

Syntax 130

Examples 130

Basic Usage - Creating a ByteBuffer 130

Basic Usage - Write Data to the Buffer 131

Basic Usage - Using DirectByteBuffer 131

Chapter 20: Bytecode Modification 133

Examples 133

What is Bytecode? 133

What's the logic behind this? 133

Well, there has to be more right? 133

How can I write / edit bytecode? 133

I'd like to learn more about bytecode! 134

How to edit jar files with ASM 134

How to load a ClassNode as a Class 137

How to rename classes in a jar file 137

Javassist Basic 138


Chapter 21: C++ Comparison 140

Introduction 140

Remarks 140

Classes Defined within Other Constructs# 140

Defined within Another Class 140

C++ 140

Java 140

Statically Defined within Another Class 140

C++ 140

Java 141

Defined within a Method 141

C++ 141

Java 141

Overriding vs Overloading 141

Polymorphism 142

Order of Construction/Destruction 142

Object Cleanup 142

Abstract Methods & Classes 143

Accessibility Modifiers 143

C++ Friend Example 143

The Dreaded Diamond Problem 144

java.lang.Object Class 144

Java Collections & C++ Containers 144

Java Collections Flowchart 144

C++ Containers Flowchart 144

Integer Types 144

Examples 145

Static Class Members 145

C++ Example 145

Java Example 145


Classes Defined within Other Constructs 146

Defined within Another Class 146

C++ 146

Java 146

Statically Defined within Another Class 146

C++ 146

Java 147

Defined within a Method 147

C++ 147

Java 147

Pass-by-value & Pass-by-reference 147

C++ Example (complete code) 147

Java Example (complete code) 148

Inheritance vs Composition 149

Outcast Downcasting 149

C++ Example 149

Java Example 149

Abstract Methods & Classes 149

Abstract Method 149

C++ 149

Java 149

Abstract Class 149

C++ 150

Java 150

Interface 150

C++ 150

Java 150

Chapter 22: Calendar and its Subclasses 151

Remarks 151

Examples 151

Creating Calendar objects 151


Increasing / Decreasing calendar fields 151

Finding AM/PM 152

Subtracting calendars 152

Chapter 23: Character encoding 153

Examples 153

Reading text from a file encoded in UTF-8 153

Writing text to a file in UTF-8 153

Getting byte representation of a string in UTF-8 154

Chapter 24: Choosing Collections 155

Introduction 155

Examples 155

Java Collections Flowchart 155

Chapter 25: Class - Java Reflection 156

Introduction 156

Examples 156

getClass() method of Object class 156

Chapter 26: Classes and Objects 157

Introduction 157

Syntax 157

Examples 157

Simplest Possible Class 157

Object Member vs Static Member 157

Overloading Methods 158

Basic Object Construction and Use 159

Constructors 162

Initializing static final fields using a static initializer 163

Explaining what is method overloading and overriding. 163

Chapter 27: Classloaders 167

Remarks 167

Examples 167

Instantiating and using a classloader 167

Implementing a custom classLoader 167


Loading an external .class file 168

Chapter 28: Collection Factory Methods 170

Introduction 170

Syntax 170

Parameters 170

Examples 170

List Factory Method Examples 170

Set Factory Method Examples 171

Map Factory Method Examples 171

Chapter 29: Collections 172

Introduction 172

Remarks 172

Examples 173

Declaring an ArrayList and adding objects 173

Constructing collections from existing data 174

Standard Collections 174

Java Collections framework 174

Google Guava Collections framework 174

Mapping Collections 174

Java Collections framework 175

Apache Commons Collections framework 175

Google Guava Collections framework 175

Join lists 176

Removing items from a List within a loop 176

INCORRECT 176

Removing in iteration of for statement Skips "Banana": 176

Removing in the enhanced for statement Throws Exception: 177

CORRECT 177

Removing in while loop using an Iterator 177

Iterating backwards 178

Iterating forward, adjusting the loop index 178


Using a "should-be-removed" list 179

Filtering a Stream 179

Using removeIf 179

Unmodifiable Collection 179

Iterating over Collections 180

Iterating over List 180

Iterating over Set 181

Iterating over Map 181

Immutable Empty Collections 182

Collections and Primitive Values 182

Removing matching items from Lists using Iterator. 183

Creating your own Iterable structure for use with Iterator or for-each loop. 184

Pitfall: concurrent modification exceptions 186

Sub Collections 186

List subList(int fromIndex, int toIndex) 186

Set subSet(fromIndex,toIndex) 187

Map subMap(fromKey,toKey) 187

Chapter 30: Command line Argument Processing 188

Syntax 188

Parameters 188

Remarks 188

Examples 188

Argument processing using GWT ToolBase 188

Processing arguments by hand 189

A command with no arguments 189

A command with two arguments 190

A command with "flag" options and at least one argument 190

Chapter 31: Common Java Pitfalls 192

Introduction 192

Examples 192

Pitfall: using == to compare primitive wrappers objects such as Integer 192


Pitfall: forgetting to free resources 193

Pitfall: memory leaks 194

Pitfall: using == to compare strings 195

Pitfall: testing a file before attempting to open it. 197

Pitfall: thinking of variables as objects 198

Example class 199

Multiple variables can point to the same object 199

The equality operator does NOT test that two objects are equal 200

Method calls do NOT pass objects at all 201

Pitfall: combining assignment and side-effects 201

Pitfall: Not understanding that String is an immutable class 202

Chapter 32: Comparable and Comparator 204

Syntax 204

Remarks 204

Examples 204

Sorting a List using Comparable or a Comparator 205

Lambda expression based comparators 208

Comparator default methods 208

Inversing the order of a comparator 208

The compareTo and compare Methods 208

Natural (comparable) vs explicit (comparator) sorting 209

Sorting Map entries 210

Creating a Comparator using comparing method 211

Chapter 33: CompletableFuture 212

Introduction 212

Examples 212

Convert blocking method to asynchonous 212

Simple Example of CompletableFuture 213

Chapter 34: Concurrent Collections 214

Introduction 214

Examples 214
Thread-safe Collections 214

Concurrent Collections 214

Thread safe but non concurrent examples 216

Insertion into ConcurrentHashMap 216

Chapter 35: Concurrent Programming (Threads) 218

Introduction 218

Remarks 218

Examples 218

Basic Multithreading 218

Producer-Consumer 219

Using ThreadLocal 220

CountDownLatch 221

Synchronization 223

Atomic operations 224

Creating basic deadlocked system 225

Pausing Execution 227

Visualizing read/write barriers while using synchronized / volatile 228

Creating a java.lang.Thread instance 229

Thread Interruption / Stopping Threads 231

Multiple producer/consumer example with shared global queue 233

Exclusive write / Concurrent read access 235

Runnable Object 237

Semaphore 237

Add two `int` arrays using a Threadpool 238

Get status of all threads started by your program excluding system threads 239

Callable and Future 240

Locks as Synchronisation aids 242

Chapter 36: Console I/O 244

Examples 244

Reading user input from the console 244

Using BufferedReader: 244

Using Scanner: 244


Using System.console: 245

Implementing Basic Command-Line Behavior 246

Aligning strings in console 247

Format strings examples 248

Chapter 37: Constructors 249

Introduction 249

Remarks 249

Examples 249

Default Constructor 249

Constructor with Arguments 250

Call parent constructor 251

Chapter 38: Converting to and from Strings 253

Examples 253

Converting other datatypes to String 253

Conversion to / from bytes 253

Base64 Encoding / Decoding 254

Parsing Strings to a Numerical Value 255

Getting a `String` from an `InputStream` 256

Converting String to other datatypes. 256

Chapter 39: Creating Images Programmatically 259

Remarks 259

Examples 259

Creating a simple image programmatically and displaying it 259

Save an Image to disk 260

Specifying image rendering quality 260

Creating an image with BufferedImage class 262

Editing and re-using image with BufferedImage 263

Setting individual pixel's color in BufferedImage 264

How to scale a BufferedImage 264

Chapter 40: Currency and Money 266

Examples 266

Add custom currency 266


Chapter 41: Date Class 267

Syntax 267

Parameters 267

Remarks 267

Examples 268

Creating Date objects 268

Comparing Date objects 269

Calendar, Date, and LocalDate 269

before, after, compareTo and equals methods 269

isBefore, isAfter, compareTo and equals methods 270

Date comparison before Java 8 270

Since Java 8 271

Converting Date to a certain String format 272

Converting String into Date 272

A basic date output 273

Convert formatted string representation of date to Date object 273

Creating a Specific Date 274

Java 8 LocalDate and LocalDateTime objects 274

Time Zones and java.util.Date 275

Convert java.util.Date to java.sql.Date 276

LocalTime 277

Chapter 42: Dates and Time (java.time.*) 278

Examples 278

Simple Date Manipulations 278

Date and time 278

Operations on dates and times 279

Instant 279

Usage of various classes of Date Time API 279

Date Time Formatting 281

Calculate Difference between 2 LocalDates 282

Chapter 43: Default Methods 283


Introduction 283

Syntax 283

Remarks 283

Default methods 283

Static methods 283

References : 284

Examples 284

Basic usage of default methods 284

Accessing other interface methods within default method 285

Accessing overridden default methods from implementing class 286

Why use Default Methods? 286

Class, Abstract class and Interface method precedence 287

Default method multiple inheritance collision 288

Chapter 44: Dequeue Interface 290

Introduction 290

Remarks 290

Examples 290

Adding Elements to Deque 290

Removing Elements from Deque 290

Retrieving Element without Removing 291

Iterating through Deque 291

Chapter 45: Disassembling and Decompiling 292

Syntax 292

Parameters 292

Examples 292

Viewing bytecode with javap 293

Chapter 46: Documenting Java Code 300

Introduction 300

Syntax 300

Remarks 301

Examples 301

Class Documentation 301


Method Documentation 302

Field Documentation 302

Package Documentation 303

Links 303

Building Javadocs From the Command Line 304

Inline Code Documentation 305

Code snippets inside documentation 306

Chapter 47: Dynamic Method Dispatch 307

Introduction 307

Remarks 307

Examples 307

Dynamic Method Dispatch - Example Code 307

Chapter 48: Encapsulation 310

Introduction 310

Remarks 310

Examples 310

Encapsulation to maintain invariants 310

Encapsulation to reduce coupling 311

Chapter 49: Enum Map 313

Introduction 313

Examples 313

Enum Map Book Example 313

Chapter 50: Enum starting with number 314

Introduction 314

Examples 314

Enum with name at begining 314

Chapter 51: Enums 315

Introduction 315

Syntax 315

Remarks 315

Restrictions 315
Tips & Tricks 315

Examples 316

Declaring and using a basic enum 316

Enums with constructors 319

Using methods and static blocks 321

Implements Interface 322

Enum Polymorphism Pattern 323

Enums with Abstract Methods 324

Documenting enums 324

Getting the values of an enum 325

Enum as a bounded type parameter 325

Get enum constant by name 326

Implement Singleton pattern with a single-element enum 326

Enum with properties (fields) 327

Convert enum to String 328

Convert using name() 328

Convert using toString() 328

By default: 328

Example of being overridden 329

Enum constant specific body 329

Zero instance enum 330

Enums with static fields 331

Compare and Contains for Enum values 332

Chapter 52: EnumSet class 334

Introduction 334

Examples 334

Enum Set Example 334

Chapter 53: Exceptions and exception handling 335

Introduction 335

Syntax 335

Examples 335

Catching an exception with try-catch 335


Try-catch with one catch block 335

Try-catch with multiple catches 336

Multi-exception catch blocks 337

Throwing an exception 337

Exception chaining 338

Custom Exceptions 339

The try-with-resources statement 340

What is a resource? 341

The basic try-with-resource statement 341

The enhanced try-with-resource statements 341

Managing multiple resources 342

Equivalence of try-with-resource and classical try-catch-finally 342

Creating and reading stacktraces 344

Printing a stacktrace 344

Understanding a stacktrace 344

Exception chaining and nested stacktraces 346

Capturing a stacktrace as a String 347

Handling InterruptedException 348

The Java Exception Hierarchy - Unchecked and Checked Exceptions 349

Checked versus Unchecked Exceptions 349

Checked exception examples 350

Introduction 352

Return statements in try catch block 354

Advanced features of Exceptions 355

Examining the callstack programmatically 355

Optimizing exception construction 355

Erasing or replacing the stacktrace 356

Suppressed exceptions 356

The try-finally and try-catch-finally statements 357

Try-finally 357

try-catch-finally 357

The 'throws' clause in a method declaration 358


What is the point of declaring unchecked exceptions as thrown? 359

Throws and method overriding 359

Chapter 54: Executor, ExecutorService and Thread pools 361

Introduction 361

Remarks 361

Examples 361

Fire and Forget - Runnable Tasks 361

ThreadPoolExecutor 362

Retrieving value from computation - Callable 363

Scheduling tasks to run at a fixed time, after a delay or repeatedly 364

Starting a task after a fixed delay 364

Starting tasks at a fixed rate 364

Starting tasks with a fixed delay 365

Handle Rejected Execution 365

submit() vs execute() exception handling differences 366

Use cases for different types of concurrency constructs 368

Wait for completion of all tasks in ExecutorService 369

Use cases for different types of ExecutorService 371

Using Thread Pools 373

Chapter 55: Expressions 374

Introduction 374

Remarks 374

Examples 374

Operator Precedence 374

Constant Expressions 375

Uses for Constant Expressions 376

Expression evaluation order 377

Simple Example 377

Example with an operator which has a side-effect 377

Expression Basics 378

The Type of an Expression 379

The value of an Expression 379


Expression Statements 379

Chapter 56: File I/O 381

Introduction 381

Examples 381

Reading all bytes to a byte[] 381

Reading an image from a file 381

Writing a byte[] to a file 381

Stream vs Writer/Reader API 382

Reading a whole file at once 383

Reading a file with a Scanner 384

Iterating over a directory and filter by file extension 384

Migrating from java.io.File to Java 7 NIO (java.nio.file.Path) 385

Point to a path 385

Paths relative to another path 385

Converting File from/to Path for use with libraries 385

Check if the file exists and delete it if it does 385

Write to a file via an OutputStream 386

Iterating on each file within a folder 386

Recursive folder iteration 387

File Read/Write Using FileInputStream/FileOutputStream 387

Reading from a binary file 389

Locking 389

Copying a file using InputStream and OutputStream 390

Reading a file using Channel and Buffer 390

Copying a file using Channel 391

Reading a file using BufferedInputStream 392

Writing a file using Channel and Buffer 392

Writing a file using PrintStream 393

Iterate over a directory printing subdirectories in it 393

Adding Directories 394

Blocking or redirecting standard output / error 394


Accessing the contents of a ZIP file 395

Reading from an existing file 395

Creating a new file 395

Chapter 57: FileUpload to AWS 397

Introduction 397

Examples 397

Upload file to s3 bucket 397

Chapter 58: Fluent Interface 400

Remarks 400

Examples 400

Truth - Fluent Testing Framework 400

Fluent programming style 400

Chapter 59: FTP (File Transfer Protocol) 403

Syntax 403

Parameters 403

Examples 403

Connecting and Logging Into a FTP Server 403

Chapter 60: Functional Interfaces 409

Introduction 409

Examples 409

List of standard Java Runtime Library functional interfaces by signature 409

Chapter 61: Generating Java Code 412

Examples 412

Generate POJO From JSON 412

Chapter 62: Generics 413

Introduction 413

Syntax 413

Remarks 413

Examples 413

Creating a Generic Class 413

Extending a generic class 414


Multiple type parameters 415

Declaring a Generic Method 416

The Diamond 417

Requiring multiple upper bounds ("extends A & B") 418

Creating a Bounded Generic Class 418

Deciding between `T`, `? super T`, and `? extends T` 420

Benefits of Generic class and interface 421

Stronger type checks at compile time 421

Elimination of casts 421

Enabling programmers to implement generic algorithms 422

Binding generic parameter to more than 1 type 422

Note: 423

Instantiating a generic type 423

Workarounds 423

Referring to the declared generic type within its own declaration 424

Use of instanceof with Generics 425

Different ways for implementing a Generic Interface (or extending a Generic Class) 426

Using Generics to auto-cast 428

Obtain class that satisfies generic parameter at runtime 428

Chapter 63: Getters and Setters 430

Introduction 430

Examples 430

Adding Getters and Setters 430

Using a setter or getter to implement a constraint 431

Why Use Getters and Setters? 431

Chapter 64: Hashtable 434

Introduction 434

Examples 434

Hashtable 434

Chapter 65: HttpURLConnection 435

Remarks 435
Examples 435

Get response body from a URL as a String 435

POST data 436

How it works 437

Delete resource 437

How it works 437

Check if resource exists 438

Explanation: 438

Example: 438

Chapter 66: Immutable Class 439

Introduction 439

Remarks 439

Examples 439

Rules to define immutable classes 439

Example without mutable refs 439

Example with mutable refs 440

What is the advantage of immutability? 441

Chapter 67: Immutable Objects 442

Remarks 442

Examples 442

Creating an immutable version of a type using defensive copying. 442

The recipe for an immutable class 443

Typical design flaws which prevent a class from being immutable 444

Chapter 68: Inheritance 448

Introduction 448

Syntax 448

Remarks 448

Examples 448

Abstract Classes 448

Static Inheritance 450

Using 'final' to restrict inheritance and overriding 451


Final classes 451

Use-cases for final classes 451

Final methods 452

The Liskov Substitution Principle 453

Inheritance 453

Inheritance and Static Methods 455

Variable shadowing 455

Narrowing and Widening of object references 456

Programming to an interface 457

Abstract class and Interface usage: "Is-a" relation vs "Has-a" capability 460

Overriding in Inheritance 463

Chapter 69: InputStreams and OutputStreams 465

Syntax 465

Remarks 465

Examples 465

Reading InputStream into a String 465

Writing bytes to an OutputStream 465

Closing Streams 466

Copying Input Stream to Output Stream 467

Wrapping Input/Output Streams 467

Useful combinations 467

List of Input/Output Stream wrappers 468

DataInputStream Example 468

Chapter 70: Installing Java (Standard Edition) 470

Introduction 470

Examples 470

Setting %PATH% and %JAVA_HOME% after installing on Windows 470

Assumptions: 470

Setup steps 470

Check your work 471

Selecting an appropriate Java SE release 471

Java release and version naming 472


What do I need for Java Development 473

Installing a Java JDK on Linux 473

Using the Package Manager 473

Installing from an Oracle Java RPM file. 475

Installing a Java JDK or JRE on Windows 475

Installing a Java JDK on macOS 476

Configuring and switching Java versions on Linux using alternatives 477

Using Alternatives 477

Arch based installs 478

Listing installed environments 478

Switching current environment 478

Post-installation checking and configuration on Linux 479

Installing oracle java on Linux with latest tar file 480

Expected output: 481

Chapter 71: Interfaces 482

Introduction 482

Syntax 482

Examples 482

Declaring and Implementing an Interface 482

Implementing multiple interfaces 483

Extending an interface 484

Using Interfaces with Generics 484

Usefulness of interfaces 487

Implementing interfaces in an abstract class 488

Default methods 489

Observer pattern implementation 489

Diamond problem 490

Use default methods to resolve compatibility issues 491

Modifiers in Interfaces 491

Variables 492

Methods 492

Strengthen bounded type parameters 492


Chapter 72: Iterator and Iterable 494

Introduction 494

Remarks 494

Examples 494

Using Iterable in for loop 494

Using the raw iterator 494

Creating your own Iterable. 495

Removing elements using an iterator 496

Chapter 73: Java Agents 498

Examples 498

Modifying classes with agents 498

Adding an agent at runtime 499

Setting up a basic agent 499

Chapter 74: Java Compiler - 'javac' 501

Remarks 501

Examples 501

The 'javac' command - getting started 501

Simple example 501

Example with packages 502

Compiling multiple files at once with 'javac'. 503

Commonly used 'javac' options 503

References 504

Compiling for a different version of Java 504

Compiling old Java with a newer compiler 504

Compiling for an older execution platform 504

Chapter 75: Java deployment 506

Introduction 506

Remarks 506

Examples 506

Making an executable JAR from the command line 506

Creating JAR, WAR and EAR files 507


Creating JAR and WAR files using Maven 508

Creating JAR, WAR and EAR files using Ant 508

Creating JAR, WAR and EAR files using an IDE 508

Creating JAR, WAR and EAR files using the jar command. 508

Introduction to Java Web Start 509

Prerequisites 509

An example JNLP file 509

Setting up the web server 510

Enabling launch via a web page 510

Launching Web Start applications from the command line 511

Creating an UberJAR for an application and its dependencies 511

Creating an UberJAR using the "jar" command 511

Creating an UberJAR using Maven 512

The advantages and drawbacks of UberJARs 512

Chapter 76: Java Editions, Versions, Releases and Distributions 513

Examples 513

Differences between Java SE JRE or Java SE JDK distributions 513

Java Runtime Environment 513

Java Development Kit 513

What is the difference between Oracle Hotspot and OpenJDK 514

Differences between Java EE, Java SE, Java ME and JavaFX 514

The Java Programming Language Platforms 514

Java SE 515

Java EE 515

Java ME 515

Java FX 516

Java SE Versions 516

Java SE Version History 516

Java SE Version Highlights 517

Chapter 77: Java Floating Point Operations 519

Introduction 519
Examples 519

Comparing floating point values 519

OverFlow and UnderFlow 521

Formatting the floating point values 522

Strict Adherence to the IEEE Specification 523

Chapter 78: Java Memory Management 524

Remarks 524

Examples 524

Finalization 524

Finalizers only run once 524

Manually triggering GC 525

Garbage collection 525

The C++ approach - new and delete 525

The Java approach - garbage collection 526

What happens when an object becomes unreachable 526

Examples of reachable and unreachable objects 527

Setting the Heap, PermGen and Stack sizes 528

Memory leaks in Java 529

Reachable objects can leak 529

Caches can be memory leaks 530

Chapter 79: Java Memory Model 531

Remarks 531

Examples 531

Motivation for the Memory Model 531

Reordering of assignments 532

Effects of memory caches 532

Proper synchronization 533

The Memory Model 533

Happens-before relationships 533

Actions 534

Program Order and Synchronization Order 534

Happens-before Order 535


Happens-before reasoning applied to some examples 535

Single-threaded code 535

Behavior of 'volatile' in an example with 2 threads 536

Volatile with three threads 537

How to avoid needing to understand the Memory Model 538

Chapter 80: Java Native Access 539

Examples 539

Introduction to JNA 539

What is JNA? 539

How can I use it? 539

Where to go now? 540

Chapter 81: Java Native Interface 541

Parameters 541

Remarks 541

Examples 541

Calling C++ methods from Java 541

Java code 541

C++ code 542

Output 543

Calling Java methods from C++ (callback) 543

Java code 543

C++ code 544

Output 544

Getting the descriptor 544

Loading native libraries 545

Target file lookup 545

Chapter 82: Java Performance Tuning 547

Examples 547

General approach 547

Reducing amount of Strings 547

An evidence-based approach to Java performance tuning 548


Chapter 83: Java Pitfalls - Exception usage 550

Introduction 550

Examples 550

Pitfall - Ignoring or squashing exceptions 550

Pitfall - Catching Throwable, Exception, Error or RuntimeException 551

Pitfall - Throwing Throwable, Exception, Error or RuntimeException 552

Declaring Throwable or Exception in a method's "throws" is problematic. 553

Pitfall - Catching InterruptedException 554

Pitfall - Using exceptions for normal flowcontrol 555

Pitfall - Excessive or inappropriate stacktraces 556

Pitfall - Directly subclassing `Throwable` 557

Chapter 84: Java Pitfalls - Language syntax 558

Introduction 558

Remarks 558

Examples 558

Pitfall - Ignoring method visibility 558

Pitfall - Missing a ‘break’ in a 'switch' case 558

Pitfall - Misplaced semicolons and missing braces 559

Pitfall - Leaving out braces: the "dangling if" and "dangling else" problems 561

Pitfall - Overloading instead of overriding 562

Pitfall - Octal literals 564

Pitfall - Declaring classes with the same names as standard classes 564

Pitfall - Using '==' to test a boolean 565

Pitfall - Wildcard imports can make your code fragile 566

Pitfall: Using 'assert' for argument or user input validation 566

Pitfall of Auto-Unboxing Null Objects into Primitives 567

Chapter 85: Java Pitfalls - Nulls and NullPointerException 569

Remarks 569

Examples 569

Pitfall - Unnecessary use of Primitive Wrappers can lead to NullPointerExceptions 569

Pitfall - Using null to represent an empty array or collection 570

Pitfall - "Making good" unexpected nulls 571


What does it mean for "a" or "b" to be null? 572

Did the null come from an uninitialized variable? 572

Does the null represent a "don't know" or "missing value"? 572

If this is a bug (or a design error) should we "make good"? 572

Is this efficient / good for code quality? 572

In summary 573

Pitfall - Returning null instead of throwing an exception 573

Pitfall - Not checking if an I/O stream isn't even initialized when closing it 573

Pitfall - Using "Yoda notation" to avoid NullPointerException 574

Chapter 86: Java Pitfalls - Performance Issues 576

Introduction 576

Remarks 576

Examples 576

Pitfall - The overheads of creating log messages 576

Solution 576

Pitfall - String concatenation in a loop does not scale 577

Pitfall - Using 'new' to create primitive wrapper instances is inefficient 578

Pitfall - Calling 'new String(String)' is inefficient 578

Pitfall - Calling System.gc() is inefficient 579

Pitfall - Over-use of primitive wrapper types is inefficient 580

Pitfall - Iterating a Map's keys can be inefficient 581

Pitfall - Using size() to test if a collection is empty is inefficient. 581

Pitfall - Efficiency concerns with regular expressions 582

Pattern and Matcher instances should be reused 582

Don't use match() when you should use find() 583

Use more efficient alternatives to regular expressions 583

Catastrophic Backtracking 584

Pitfall - Interning strings so that you can use == is a bad idea 585

Fragility 585

Costs of using 'intern()' 585

The impact on garbage collection 586

The string pool hashtable size 586


Interning as a potential denial of service vector 587

Pitfall - Small reads / writes on unbuffered streams are inefficient 587

What about character-based streams? 588

Why do buffered streams make this much difference? 588

Are buffered streams always a win? 589

Is this the fastest way to copy a file in Java? 589

Chapter 87: Java Pitfalls - Threads and Concurrency 590

Examples 590

Pitfall: incorrect use of wait() / notify() 590

The "Lost Notification" problem 590

The "Illegal Monitor State" bug 590

Wait / notify is too low-level 591

Pitfall - Extending 'java.lang.Thread' 591

Pitfall - Too many threads makes an application slower. 592

Pitfall - Thread creation is relatively expensive 593

Pitfall: Shared variables require proper synchronization 594

Will it work as intended? 595

How do we fix the problem? 595

But isn't assignment atomic? 596

Why did they do this? 596

Why can't I reproduce this? 597

Chapter 88: Java plugin system implementations 599

Remarks 599

Examples 599

Using URLClassLoader 599

Chapter 89: Java Print Service 604

Introduction 604

Examples 604

Discovering the available print services 604

Discovering the default print service 604

Creating a print job from a print service 605

Building the Doc that will be printed 605


Defining print request attributes 606

Listening print job request status change 606

The PrintJobEvent pje argument 608

Another way to achieve the same goal 608

Chapter 90: Java SE 7 Features 609

Introduction 609

Remarks 609

Examples 609

New Java SE 7 programming language features 609

Binary Literals 609

The try-with-resources statement 610

Underscores in Numeric Literals 610

Type Inference for Generic Instance Creation 610

Strings in switch Statements 611

Chapter 91: Java SE 8 Features 612

Introduction 612

Remarks 612

Examples 612

New Java SE 8 programming language features 612

Chapter 92: Java Sockets 614

Introduction 614

Remarks 614

Examples 614

A simple TCP echo back server 614

Chapter 93: Java Virtual Machine (JVM) 618

Examples 618

These are the basics. 618

Chapter 94: JavaBean 619

Introduction 619

Syntax 619

Remarks 619
Examples 620

Basic Java Bean 620

Chapter 95: JAXB 621

Introduction 621

Syntax 621

Parameters 621

Remarks 621

Examples 621

Writing an XML file (marshalling an object) 621

Reading an XML file (unmarshalling) 622

Using XmlAdapter to generate desired xml format 623

Automatic field/property XML mapping configuration (@XmlAccessorType) 624

Manual field/property XML mapping configuration 626

Specifying a XmlAdapter instance to (re)use existing data 626

Example 627

User class 627

Adapter 627

Example XMLs 628

Using the adapter 629

Binding an XML namespace to a serializable Java class. 629

Using XmlAdapter to trim string. 630

Chapter 96: JAX-WS 631

Examples 631

Basic Authentication 631

Chapter 97: JMX 632

Introduction 632

Examples 632

Simple example with Platform MBean Server 632

Chapter 98: JNDI 637

Examples 637

RMI through JNDI 637

Chapter 99: JShell 641


Introduction 641

Syntax 641

Remarks 641

Default Imports 641

Examples 641

Entering and Exiting JShell 642

Starting JShell 642

Exiting JShell 642

Expressions 642

Variables 642

Methods and Classes 643

Editting Snippets 643

Chapter 100: JSON in Java 645

Introduction 645

Remarks 645

Examples 645

Encoding data as JSON 645

Decoding JSON data 646

optXXX vs getXXX methods 646

Object To JSON (Gson Library) 647

JSON To Object (Gson Library) 647

Extract single element from JSON 647

Using Jackson Object Mapper 648

Details 648

ObjectMapper instance 648

Deserialization: 648

Method for serialization: 649

JSON Iteration 649

JSON Builder - chaining methods 649

JSONObject.NULL 650

JsonArray to Java List (Gson Library) 650

Deserialize JSON collection to collection of Objects using Jackson 651


Deserializing JSON array 651

TypeFactory approach 651

TypeReference approach 652

Deserializing JSON map 652

TypeFactory approach 652

TypeReference approach 652

Details 652

Note 652

Chapter 101: Just in Time (JIT) compiler 654

Remarks 654

History 654

Examples 654

Overview 654

Chapter 102: JVM Flags 657

Remarks 657

Examples 657

-XXaggressive 657

-XXallocClearChunks 657

-XXallocClearChunkSize 658

-XXcallProfiling 658

-XXdisableFatSpin 658

-XXdisableGCHeuristics 659

-XXdumpSize 659

-XXexitOnOutOfMemory 659

Chapter 103: JVM Tool Interface 661

Remarks 661

Examples 661

Iterate over objects reachable from object (Heap 1.0) 661

Get JVMTI environment 663

Example of initialization inside of Agent_OnLoad method 664

Chapter 104: Lambda Expressions 665


Introduction 665

Syntax 665

Examples 665

Using Lambda Expressions to Sort a Collection 665

Sorting lists 665

Sorting maps 666

Introduction to Java lambdas 667

Functional Interfaces 667

Lambda Expressions 668

Implicit Returns 669

Accessing Local Variables (value closures) 669

Accepting Lambdas 670

The Type of a Lambda Expression 670

Method References 670

Instance method reference (to an arbitrary instance) 671

Instance method reference (to a specific instance) 671

Static method reference 671

Reference to a constructor 672

Cheat-Sheet 672

Implementing multiple interfaces 672

Lambdas and Execute-around Pattern 673

Using lambda expression with your own functional interface 674

`return` only returns from the lambda, not the outer method 674

Java Closures with lambda expressions. 676

Lambda - Listener Example 678

Traditional style to Lambda style 678

Lambdas and memory utilization 679

Using lambda expressions & predicates to get a certain value(s) from a list 680

Chapter 105: LinkedHashMap 682

Introduction 682

Examples 682
Java LinkedHashMap class 682

Chapter 106: List vs SET 684

Introduction 684

Examples 684

List vs Set 684

Chapter 107: Lists 685

Introduction 685

Syntax 685

Remarks 685

Examples 686

Sorting a generic list 686

Creating a List 687

Positional Access Operations 689

Iterating over elements in a list 690

Removing elements from list B that are present in the list A 691

Finding common elements between 2 lists 692

Convert a list of integers to a list of strings 692

Creating, Adding and Removing element from an ArrayList 692

In-place replacement of a List element 693

Making a list unmodifiable 694

Moving objects around in the list 694

Classes implementing List - Pros and Cons 695

Classes implementing List 695

Pros and Cons of each implementation in term of time complexity 695

ArrayList 696

AttributeList 696

CopyOnWriteArrayList 696

LinkedList 696

RoleList 697

RoleUnresolvedList 697

Stack 697

Vector 697
Chapter 108: Literals 699

Introduction 699

Examples 699

Hexadecimal, Octal and Binary literals 699

Using underscore to improve readability 699

Escape sequences in literals 700

Unicode escapes 701

Escaping in regexes 701

Decimal Integer literals 701

Ordinary integer literals 701

Long integer literals 702

Boolean literals 702

String literals 702

Long strings 703

Interning of string literals 703

The Null literal 703

Floating-point literals 704

Simple decimal forms 704

Scaled decimal forms 705

Hexadecimal forms 705

Underscores 705

Special cases 706

Character literals 706

Chapter 109: Local Inner Class 707

Introduction 707

Examples 707

Local Inner Class 707

Chapter 110: Localization and Internationalization 708

Remarks 708

General Resources 708

Java Resources 708


Examples 708

Automatically formatted Dates using "locale" 708

Let Java do the work for you 709

String Comparison 709

Locale 709

Language 710

Creating a Locale 710

Java ResourceBundle 710

Setting Locale 710

Chapter 111: LocalTime 712

Syntax 712

Parameters 712

Remarks 712

Examples 712

Time Modification 712

Time Zones and their time difference 713

Amount of time between two LocalTime 713

Intro 714

Chapter 112: log4j / log4j2 716

Introduction 716

Syntax 716

Remarks 716

End of Life for Log4j 1 reached 716

Examples 717

How to get Log4j 717

How to use Log4j in Java code 718

Setting up property file 718

Basic log4j2.xml configuration file 719

Migrating from log4j 1.x to 2.x 719

Properties-File to log to DB 720

Filter Logoutput by level (log4j 1.x) 721


Chapter 113: Logging (java.util.logging) 723

Examples 723

Using the default logger 723

Logging levels 723

Logging complex messages (efficiently) 724

Chapter 114: Maps 727

Introduction 727

Remarks 727

Examples 727

Add an element 727

Add multiple items 728

Using Default Methods of Map from Java 8 729

Clear the map 731

Iterating through the contents of a Map 732

Merging, combine and composing Maps 733

Composing Map<X,Y> and Map<Y,Z> to get Map<X,Z> 733

Check if key exists 734

Maps can contain null values 734

Iterating Map Entries Efficiently 734

Use custom object as key 737

Usage of HashMap 738

Creating and Initializing Maps 739

Introduction 739

Chapter 115: Modules 742

Syntax 742

Remarks 742

Examples 742

Defining a basic module 742

Chapter 116: Multi-Release JAR Files 744

Introduction 744

Examples 744
Example of a multi-release Jar file's contents 744

Creating a multi-release Jar using the jar tool 744

URL of a loaded class inside a multi-release Jar 746

Chapter 117: Nashorn JavaScript engine 747

Introduction 747

Syntax 747

Remarks 747

Examples 747

Set global variables 747

Hello Nashorn 748

Execute JavaScript file 748

Intercept script output 748

Evaluate Arithmetic Strings 749

Usage of Java objects in JavaScript in Nashorn 749

Implementing an interface from script 750

Set and get global variables 751

Chapter 118: Nested and Inner Classes 752

Introduction 752

Syntax 752

Remarks 752

Terminology and classification 752

Semantic differences 753

Examples 753

A Simple Stack Using a Nested Class 753

Static vs Non Static Nested Classes 754

Access Modifiers for Inner Classes 756

Anonymous Inner Classes 757

Constructors 758

Method Local Inner Classes 758

Accessing the outer class from a non-static inner class 759

Create instance of non-static inner class from outside 760

Chapter 119: Networking 761


Syntax 761

Examples 761

Basic Client and Server Communication using a Socket 761

Server: Start, and wait for incoming connections 761

Server: Handling clients 761

Client: Connect to the server and send a message 762

Closing Sockets and Handling Exceptions 762

Basic Server and Client - complete examples 762

Loading TrustStore and KeyStore from InputStream 764

Socket example - reading a web page using a simple socket 765

Basic Client/Server Communication using UDP (Datagram) 765

Multicasting 766

Temporarily disable SSL verification (for testing purposes) 768

Downloading a file using Channel 769

Notes 770

Chapter 120: New File I/O 771

Syntax 771

Examples 771

Creating paths 771

Retrieving information about a path 771

Manipulating paths 772

Joining Two Paths 772

Normalizing a path 772

Retrieving information using the filesystem 772

Checking existence 772

Checking whether a path points to a file or a directory 773

Getting properties 773

Getting MIME type 773

Reading files 774

Writing files 774

Chapter 121: NIO - Networking 775


Remarks 775

Examples 775

Using Selector to wait for events (example with OP_CONNECT) 775

Chapter 122: Non-Access Modifiers 777

Introduction 777

Examples 777

final 777

volatile 778

static 779

abstract 780

synchronized 781

transient 782

strictfp 782

Chapter 123: NumberFormat 783

Examples 783

NumberFormat 783

Chapter 124: Object Class Methods and Constructor 784

Introduction 784

Syntax 784

Examples 784

toString() method 784

equals() method 785

Class Comparison 787

hashCode() method 788

Using Arrays.hashCode() as a short cut 789

Internal caching of hash codes 790

wait() and notify() methods 791

getClass() method 792

clone() method 793

finalize() method 794

Object constructor 795

Chapter 125: Object Cloning 798


Remarks 798

Examples 798

Cloning using a copy constructor 798

Cloning by implementing Clonable interface 798

Cloning performing a shallow copy 799

Cloning performing a deep copy 800

Cloning using a copy factory 801

Chapter 126: Object References 802

Remarks 802

Examples 802

Object References as method parameters 802

Chapter 127: Operators 806

Introduction 806

Remarks 806

Examples 806

The String Concatenation Operator (+) 806

Optimization and efficiency 807

The Arithmetic Operators (+, -, *, /, %) 808

Operand and result types, and numeric promotion 809

The meaning of division 809

The meaning of remainder 810

Integer Overflow 810

Floating point INF and NAN values 811

The Equality Operators (==, !=) 811

The Numeric == and != operators 812

The Boolean == and != operators 812

The Reference == and != operators 813

About the NaN edge-cases 813

The Increment/Decrement Operators (++/--) 813

The Conditional Operator (? :) 814

Syntax 814
Common Usage 815

The Bitwise and Logical Operators (~, &, |, ^) 816

Operand types and result types. 817

The Instanceof Operator 817

The Assignment Operators (=, +=, -=, *=, /=, %=, <<=, >>= , >>>=, &=, |= and ^=) 818

The conditional-and and conditional-or Operators ( && and || ) 820

Example - using && as a guard in an expression 821

Example - using && to avoid a costly calculation 821

The Shift Operators (<<, >> and >>>) 821

The Lambda operator ( -> ) 823

The Relational Operators (<, <=, >, >=) 823

Chapter 128: Optional 825

Introduction 825

Syntax 825

Examples 825

Return default value if Optional is empty 825

Map 826

Throw an exception, if there is no value 827

Filter 827

Using Optional containers for primitive number types 828

Run code only if there is a value present 828

Lazily provide a default value using a Supplier 828

FlatMap 829

Chapter 129: Oracle Official Code Standard 830

Introduction 830

Remarks 830

Examples 830

Naming Conventions 830

Package names 830

Class, Interface and Enum Names 830

Method Names 831

Variables 831
Type Variables 831

Constants 831

Other guidelines on naming 831

Java Source Files 832

Special Characters 832

Package declaration 832

Import statements 832

Wildcard imports 833

Class Structure 833

Order of class members 833

Grouping of class members 834

Modifiers 834

Indentation 835

Wrapping statements 835

Wrapping Method Declarations 836

Wrapping Expressions 837

Whitespace 837

Vertical Whitespace 837

Horizontal Whitespace 837

Variable Declarations 838

Annotations 838

Lambda Expressions 839

Redundant Parentheses 839

Literals 840

Braces 840

Short forms 840

Chapter 130: Packages 842

Introduction 842

Remarks 842

Examples 842

Using Packages to create classes with the same name 842


Using Package Protected Scope 842

Chapter 131: Parallel programming with Fork/Join framework 844

Examples 844

Fork/Join Tasks in Java 844

Chapter 132: Polymorphism 846

Introduction 846

Remarks 846

Examples 846

Method Overloading 846

Method Overriding 848

Adding behaviour by adding classes without touching existing code 849

Virtual functions 850

Polymorphism and different types of overriding 851

Chapter 133: Preferences 855

Examples 855

Adding event listeners 855

PreferenceChangeEvent 855

NodeChangeEvent 855

Getting sub-nodes of Preferences 856

Coordinating preferences access across multiple application instances 857

Exporting preferences 857

Importing preferences 858

Removing event listeners 859

Getting preferences values 860

Setting preferences values 860

Using preferences 861

Chapter 134: Primitive Data Types 862

Introduction 862

Syntax 862

Remarks 862

Examples 863

The int primitive 863


The short primitive 864

The long primitive 864

The boolean primitive 865

The byte primitive 866

The float primitive 866

The double primitive 867

The char primitive 868

Negative value representation 869

Memory consumption of primitives vs. boxed primitives 870

Boxed value caches 871

Converting Primitives 871

Primitive Types Cheatsheet 872

Chapter 135: Process 874

Remarks 874

Examples 874

Simple example (Java version < 1.5) 874

Using the ProcessBuilder class 874

Blocking vs. Non-Blocking Calls 875

ch.vorburger.exec 876

Pitfall: Runtime.exec, Process and ProcessBuilder don't understand shell syntax 876

Spaces in pathnames 876

Redirection, pipelines and other shell syntax 877

Shell builtin commands don't work 878

Chapter 136: Properties Class 879

Introduction 879

Syntax 879

Remarks 879

Examples 880

Loading properties 880

Property files caveat: trailing whitespace 880

Saving Properties as XML 882

Chapter 137: Queues and Deques 885


Examples 885

The usage of the PriorityQueue 885

LinkedList as a FIFO Queue 885

Stacks 886

What is a Stack? 886

Stack API 886

Example 886

BlockingQueue 887

Queue Interface 888

Deque 889

Adding and Accessing Elements 890

Removing Elements 890

Chapter 138: Random Number Generation 891

Remarks 891

Examples 891

Pseudo Random Numbers 891

Pseudo Random Numbers in Specific Range 891

Generating cryptographically secure pseudorandom numbers 892

Select random numbers without duplicates 893

Generating Random Numbers with a Specified Seed 894

Generating Random number using apache-common lang3 894

Chapter 139: Readers and Writers 896

Introduction 896

Examples 896

BufferedReader 896

Introduction 896

Basics of using a BufferedReader 896

The BufferedReader buffer size 897

The BufferedReader.readLine() method 897

Example: reading all lines of a File into a List 897

StringWriter Example 897


Chapter 140: Recursion 899

Introduction 899

Remarks 899

Designing a Recursive Method 899

Output 899

Java and Tail-call elimination 900

Examples 900

The basic idea of recursion 900

Computing the Nth Fibonacci Number 901

Computing the sum of integers from 1 to N 901

Computing the Nth power of a number 901

Reverse a string using Recursion 902

Traversing a Tree data structure with recursion 902

Types of Recursion 903

StackOverflowError & recursion to loop 903

Example 903

Workaround 904

Example 904

Deep recursion is problematic in Java 906

Why tail-call elimination is not implemented in Java (yet) 907

Chapter 141: Reference Data Types 908

Examples 908

Instantiating a reference type 908

Dereferencing 908

Chapter 142: Reference Types 910

Examples 910

Different Reference Types 910

Chapter 143: Reflection API 912

Introduction 912

Remarks 912

Performance 912
Examples 912

Introduction 912

Invoking a method 914

Getting and Setting fields 914

Call constructor 915

Getting the Constructor Object 915

New Instance using Constructor Object 916

Getting the Constants of an Enumeration 916

Get Class given its (fully qualified) name 917

Call overloaded constructors using reflection 918

Misuse of Reflection API to change private and final variables 918

Call constructor of nested class 920

Dynamic Proxies 920

Evil Java hacks with Reflection 921

Chapter 144: Regular Expressions 924

Introduction 924

Syntax 924

Remarks 924

Imports 924

Pitfalls 924

Important Symbols Explained 924

Further reading 925

Examples 925

Using capture groups 925

Using regex with custom behaviour by compiling the Pattern with flags 926

Escape Characters 926

Matching with a regex literal. 927

Not matching a given string 927

Matching a backslash 928

Chapter 145: Remote Method Invocation (RMI) 930

Remarks 930

Examples 930
Client-Server: invoking methods in one JVM from another 930

Callback: invoking methods on a "client" 932

Overview 932

The shared remote interfaces 932

The implementations 933

Simple RMI example with Client and Server implementation 936

Server Package 936

Client package 937

Test your application 939

Chapter 146: Resources (on classpath) 940

Introduction 940

Remarks 940

Examples 941

Loading an image from a resource 941

Loading default configuration 942

Loading same-name resource from multiple JARs 942

Finding and reading resources using a classloader 942

Absolute and relative resource paths 943

Obtaining a Class or Classloader 943

The get methods 943

Chapter 147: RSA Encryption 945

Examples 945

An example using a hybrid cryptosystem consisting of OAEP and GCM 945

Chapter 148: Runtime Commands 950

Examples 950

Adding shutdown hooks 950

Chapter 149: Scanner 951

Syntax 951

Parameters 951

Remarks 951

Examples 951

Reading system input using Scanner 951


Reading file input using Scanner 951

Read the entire input as a String using Scanner 952

Using custom delimiters 952

General Pattern that does most commonly asked about tasks 953

Read an int from the command line 955

Carefully Closing a Scanner 955

Chapter 150: Secure objects 956

Syntax 956

Examples 956

SealedObject (javax.crypto.SealedObject) 956

SignedObject (java.security.SignedObject) 956

Chapter 151: Security & Cryptography 958

Examples 958

Compute Cryptographic Hashes 958

Generate Cryptographically Random Data 958

Generate Public / Private Key Pairs 959

Compute and Verify Digital Signatures 959

Encrypt and Decrypt Data with Public / Private Keys 960

Chapter 152: Security & Cryptography 962

Introduction 962

Remarks 962

Examples 962

The JCE 962

Keys and Key Management 962

Common Java vulnerabilities 962

Networking Concerns 963

Randomness and You 963

Hashing and Validation 963

Chapter 153: SecurityManager 964

Examples 964

Enabling the SecurityManager 964

Sandboxing classes loaded by a ClassLoader 964


Implementing policy deny rules 965

The DeniedPermission class 966

The DenyingPolicy class 970

Demo 972

Chapter 154: Serialization 974

Introduction 974

Examples 974

Basic Serialization in Java 974

Serialization with Gson 976

Serialization with Jackson 2 977

Custom Serialization 978

Versioning and serialVersionUID 980

Compatible Changes 981

Incompatible Changes 982

Custom JSON Deserialization with Jackson 982

Chapter 155: ServiceLoader 985

Remarks 985

Examples 985

Logger Service 985

Service 985

Implementations of the service 985

META-INF/services/servicetest.Logger 986

Usage 986

Simple ServiceLoader Example 987

Chapter 156: Sets 989

Examples 989

Declaring a HashSet with values 989

Types and Usage of Sets 989

HashSet - Random Sorting 989

LinkedHashSet - Insertion Order 989

TreeSet - By compareTo() or Comparator 990


Initialization 990

Basics of Set 991

Create a list from an existing Set 992

Eliminating duplicates using Set 993

Chapter 157: Singletons 994

Introduction 994

Examples 994

Enum Singleton 994

Thread safe Singleton with double checked locking 994

Singleton without use of Enum (eager initialization) 995

Thread-safe lazy initialization using holder class | Bill Pugh Singleton implementation 996

Extending singleton (singleton inheritance) 996

Chapter 158: Sockets 1000

Introduction 1000

Examples 1000

Read from socket 1000

Chapter 159: SortedMap 1001

Introduction 1001

Examples 1001

Introduction to sorted Map. 1001

Chapter 160: Splitting a string into fixed length parts 1003

Remarks 1003

Examples 1003

Break a string up into substrings all of a known length 1003

Break a string up into substrings all of variable length 1003

Chapter 161: Stack-Walking API 1004

Introduction 1004

Examples 1004

Print all stack frames of the current thread 1004

Print current caller class 1005

Showing reflection and other hidden frames 1005


Chapter 162: Streams 1007

Introduction 1007

Syntax 1007

Examples 1007

Using Streams 1007

Closing Streams 1008

Processing Order 1009

Differences from Containers (or Collections) 1010

Collect Elements of a Stream into a Collection 1010

Collect with toList() and toSet() 1010

Explicit control over the implementation of List or Set 1010

Cheat-Sheet 1012

Infinite Streams 1013

Consuming Streams 1014

h21 1015

Creating a Frequency Map 1015

Parallel Stream 1016

Performance impact 1016

Converting a Stream of Optional to a Stream of Values 1017

Creating a Stream 1017

Finding Statistics about Numerical Streams 1018

Get a Slice of a Stream 1019

Concatenate Streams 1019

IntStream to String 1020

Sort Using Stream 1020

Streams of Primitives 1021

Collect Results of a Stream into an Array 1021

Finding the First Element that Matches a Predicate 1021

Using IntStream to iterate over indexes 1022

Flatten Streams with flatMap() 1022

Create a Map based on a Stream 1023

Generating random Strings using Streams 1024


Using Streams to Implement Mathematical Functions 1025

Using Streams and Method References to Write Self-Documenting Processes 1025

Using Streams of Map.Entry to Preserve Initial Values after Mapping 1026

Stream operations categories 1027

Intermediate Operations: 1027

Terminal Operations 1027

Stateless Operations 1027

Stateful operations 1028

Converting an iterator to a stream 1028

Reduction with Streams 1028

Joining a stream to a single String 1031

Chapter 163: String Tokenizer 1033

Introduction 1033

Examples 1033

StringTokenizer Split by space 1033

StringTokenizer Split by comma ',' 1033

Chapter 164: StringBuffer 1035

Introduction 1035

Examples 1035

String Buffer class 1035

Chapter 165: StringBuilder 1037

Introduction 1037

Syntax 1037

Remarks 1037

Examples 1037

Repeat a String n times 1037

Comparing StringBuffer, StringBuilder, Formatter and StringJoiner 1038

Chapter 166: Strings 1040

Introduction 1040

Remarks 1040

Examples 1041
Comparing Strings 1041

Do not use the == operator to compare Strings 1042

Comparing Strings in a switch statement 1042

Comparing Strings with constant values 1043

String orderings 1043

Comparing with interned Strings 1043

Changing the case of characters within a String 1044

Finding a String Within Another String 1046

Getting the length of a String 1047

Substrings 1047

Getting the nth character in a String 1048

Platform independent new line separator 1048

Adding toString() method for custom objects 1049

Splitting Strings 1050

Joining Strings with a delimiter 1052

Reversing Strings 1053

Counting occurrences of a substring or character in a string 1054

String concatenation and StringBuilders 1054

Replacing parts of Strings 1056

Exact match 1056

Replace single character with another single character: 1056

Replace sequence of characters with another sequence of characters: 1056

Regex 1057

Replace all matches: 1057

Replace first match only: 1057

Remove Whitespace from the Beginning and End of a String 1057

String pool and heap storage 1058

Case insensitive switch 1060

Chapter 167: sun.misc.Unsafe 1061

Remarks 1061

Examples 1061
Instantiating sun.misc.Unsafe via reflection 1061

Instantiating sun.misc.Unsafe via bootclasspath 1061

Getting Instance of Unsafe 1062

Uses of Unsafe 1062

Chapter 168: super keyword 1064

Examples 1064

Super keyword use with examples 1064

Constructor Level 1064

Method Level 1065

Variable Level 1065

Chapter 169: The Classpath 1067

Introduction 1067

Remarks 1067

Examples 1067

Different ways to specify the classpath 1067

Adding all JARs in a directory to the classpath 1068

Classpath path syntax 1068

Dynamic Classpath 1069

Load a resource from the classpath 1069

Mapping classnames to pathnames 1070

What the classpath means: how searches work 1070

The bootstrap classpath 1071

Chapter 170: The Java Command - 'java' and 'javaw' 1073

Syntax 1073

Remarks 1073

Examples 1073

Running an executable JAR file 1073

Running a Java applications via a "main" class 1074

Running the HelloWorld class 1074

Specifying a classpath 1074

Entry point classes 1074

JavaFX entry-points 1075


Troubleshooting the 'java' command 1075

"Command not found" 1075

"Could not find or load main class" 1076

"Main method not found in class <name>" 1077

Other Resources 1077

Running a Java application with library dependencies 1077

Spaces and other special characters in arguments 1078

Solutions using a POSIX shell 1079

Solution for Windows 1080

Java Options 1080

Setting system properties with -D 1080

Memory, Stack and Garbage Collector options 1081

Enabling and disabling assertions 1081

Selecting the VM type 1081

Chapter 171: The java.util.Objects Class 1083

Examples 1083

Basic use for object null check 1083

For null check in method 1083

For not null check in method 1083

Objects.nonNull() method reference use in stream api 1083

Chapter 172: ThreadLocal 1084

Remarks 1084

Examples 1084

ThreadLocal Java 8 functional initialization 1084

Basic ThreadLocal usage 1084

Multiple threads with one shared object 1086

Chapter 173: TreeMap and TreeSet 1088

Introduction 1088

Examples 1088

TreeMap of a simple Java type 1088

TreeSet of a simple Java Type 1089


TreeMap/TreeSet of a custom Java type 1089

TreeMap and TreeSet Thread Safety 1091

Chapter 174: Type Conversion 1093

Syntax 1093

Examples 1093

Non-numeric primitive casting 1093

Numeric primitive casting 1093

Object casting 1094

Basic Numeric Promotion 1094

Testing if an object can be cast using instanceof 1094

Chapter 175: Unit Testing 1096

Introduction 1096

Remarks 1096

Unit Test Frameworks 1096

Unit Testing Tools 1096

Examples 1096

What is Unit Testing? 1096

Tests need to be automated 1098

Tests need to be fine-grained 1098

Enter unit-testing 1099

Chapter 176: Using Other Scripting Languages in Java 1100

Introduction 1100

Remarks 1100

Examples 1100

Evaluating A javascript file in -scripting mode of nashorn 1100

Chapter 177: Using the static keyword 1103

Syntax 1103

Examples 1103

Using static to declare constants 1103

Using static with this 1103

Reference to non-static member from static context 1104


Chapter 178: Using ThreadPoolExecutor in MultiThreaded applications. 1106

Introduction 1106

Examples 1106

Performing Asynchronous Tasks Where No Return Value Is Needed Using a Runnable Class Insta 1106

Performing Asynchronous Tasks Where a Return Value Is Needed Using a Callable Class Instan 1108

Defining Asynchronous Tasks Inline using Lambdas 1110

Chapter 179: Varargs (Variable Argument) 1113

Remarks 1113

Examples 1113

Specifying a varargs parameter 1113

Working with Varargs parameters 1113

Chapter 180: Visibility (controlling access to members of a class) 1115

Syntax 1115

Remarks 1115

Examples 1116

Interface members 1116

Public Visibility 1116

Private Visibility 1116

Package Visibility 1117

Protected Visibility 1118

Summary of Class Member Access Modifiers 1118

Chapter 181: WeakHashMap 1119

Introduction 1119

Examples 1119

Concepts of WeakHashmap 1119

Chapter 182: XJC 1121

Introduction 1121

Syntax 1121

Parameters 1121

Remarks 1121

Examples 1121

Generating Java code from simple XSD file 1121


XSD schema (schema.xsd) 1121

Using xjc 1122

Result files 1122

package-info.java 1124

Chapter 183: XML Parsing using the JAXP APIs 1125

Remarks 1125

Principles of the DOM interface 1125

Principles of the SAX interface 1125

Principles of the StAX interface 1126

Examples 1126

Parsing and navigating a document using the DOM API 1126

Parsing a document using the StAX API 1127

Chapter 184: XML XPath Evaluation 1130

Remarks 1130

Examples 1130

Evaluating a NodeList in an XML document 1130

Parsing multiple XPath Expressions in a single XML 1131

Parsing single XPath Expression multiple times in an XML 1131

Chapter 185: XOM - XML Object Model 1133

Examples 1133

Reading a XML file 1133

Writing to a XML File 1135

Credits 1139
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: java-language

It is an unofficial and free Java Language ebook created for educational purposes. All the content
is extracted from Stack Overflow Documentation, which is written by many hardworking individuals
at Stack Overflow. It is neither affiliated with Stack Overflow nor official Java Language.

The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.

Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]

https://riptutorial.com/ 1
Chapter 1: Getting started with Java
Language
Remarks
The Java programming language is...

• General-purpose: It is designed to be used for writing software in a wide variety of


application domains, and lacks specialized features for any specific domain.

• Class-based: Its object structure is defined in classes. Class instances always have those
fields and methods specified in their class definitions (see Classes and Objects). This is in
contrast to non-class-based languages such as JavaScript.

• Statically-typed: the compiler checks at compile time that variable types are respected. For
example, if a method expects an argument of type String, that argument must in fact be a
string when the method is called.

• Object-oriented: most things in a Java program are class instances, i.e. bundles of state
(fields) and behavior (methods which operate on data and form the object's interface to the
outside world).

• Portable: It can be compiled on any platform with javac and the resultant class files can run
on any platform that has a JVM.

Java is intended to let application developers "write once, run anywhere" (WORA), meaning that
compiled Java code can run on all platforms that support Java without the need for recompilation.

Java code is compiled to bytecode (the .class files) which in turn get interpreted by the Java
Virtual Machine (JVM). In theory, bytecode created by one Java compiler should run the same
way on any JVM, even on a different kind of computer. The JVM might (and in real-world
programs will) choose to compile into native machine commands the parts of the bytecode that are
executed often. This is called "Just-in-time (JIT) compilation".

Java Editions and Versions


There are three "editions" of Java defined by Sun / Oracle:

• Java Standard Edition (SE) is the edition that is designed for general use.
• Java Enterprise Edition (EE) adds a range of facilities for building "enterprise grade" services
in Java. Java EE is covered separately.
• Java Micro Edition (ME) is based on a subset of Java SE and is intended for use on small
devices with limited resources.

There is a separate topic on Java SE / EE / ME editions.

https://riptutorial.com/ 2
Each edition has multiple versions. The Java SE versions are listed below.

Installing Java
There is a separate topic on Installing Java (Standard Edition).

Compiling and running Java programs


There are separate topics on:

• Compiling Java source code


• Java deployment including creating JAR files
• Running Java applications
• The Classpath

What's next?
Here are links to subjects to continue learning and understanding the Java programming
language. These subjects are the basics of the Java programming to get you started.

• Primitive Data Types in Java


• Operators in Java
• Strings in Java
• Basic Control Structures in Java
• Classes and Objects in Java
• Arrays in Java
• Java code standards

Testing
While Java does not have any support for testing in the standard library, there are 3rd-party
libraries that are designed to support testing. The two most popular unit testing libraries are:

• JUnit (Official Site)


• TestNG (Official Site)

Other
• Design patterns for Java are covered in Design Patterns.
• Programming for Android is covered in Android.
• Java Enterprise Edition technologies are covered in Java EE.
• The Oracle JavaFX technologies are covered in JavaFX.

https://riptutorial.com/ 3
1. In Versions section the end-of-life (free) date is when Oracle will stop posting further updates of Java SE to its
public download sites. Customers who need continued access to critical bug fixes and security fixes as well as general
maintenance for Java SE can get long term support through Oracle Java SE Support.

Versions

Java SE Version Code Name End-of-life (free1) Release Date

Java SE 9 (Early Access) 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

Examples
Creating Your First Java Program

Create a new file in your text editor or IDE named HelloWorld.java. Then paste this code block into
the file and save:

public class HelloWorld {


public static void main(String[] args) {
System.out.println("Hello, World!");
}
}

Run live on Ideone

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

https://riptutorial.com/ 4
recommend against underscores (_) and dollar signs ($).

To compile, open a terminal window and navigate to the directory of HelloWorld.java:

cd /path/to/containing/folder/

Note: cd is the terminal command to change directory.

Enter javac followed by the file name and extension as follows:

$ 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.

In case you get this on windows, to resolve, first try browsing to your javac.exe path, it's most
probably in your C:\Program Files\Java\jdk(version number)\bin. Then try running it with below.

$ C:\Program Files\Java\jdk(version number)\bin\javac HelloWorld.java

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

To edit the PATH environment variable in Windows XP/Vista/7/8/10:

• Control Panel ⇒ System ⇒ Advanced system settings


• Switch to "Advanced" tab ⇒ Environment Variables
• In "System Variables", scroll down to select "PATH" ⇒ Edit

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.

Variable name : PATH


Variable value : c:\Program Files\Java\jdk1.8.0_xx\bin;[Existing Entries...]

Now this should resolve.

For Linux Based systems try here.

Note: The javac command invokes the Java compiler.

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

https://riptutorial.com/ 5
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

Note: The java command runs a Java application.

This will output to your console:

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:

• A JDK is installed (e.g. Oracle, OpenJDK and other sources)


• Your environment variables are properly set up

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).

A closer look at the Hello World program


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.

public class HelloWorld {

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).

public static void main(String[] args) {

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

https://riptutorial.com/ 6
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()).

This main method accepts:

• An array (typically called args) of Strings passed as arguments to main function (e.g. from
command line arguments).

Almost all of this is required for a Java entry point method.

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.

Inside the main method, we see the following statement:

System.out.println("Hello, World!");

Let's break down this statement element-by-element:

Element Purpose

this denotes that the subsequent expression will call upon the System class, from
System
the java.lang package.

this is a "dot operator". Dot operators provide you access to a classes members
. 1; i.e. its fields (variables) and its methods. In this case, this dot operator allows
you to reference the out static field within the System class.

this is the name of the static field of PrintStream type within the System class
out
containing the standard output functionality.

this is another dot operator. This dot operator provides access to the println
.
method within the out variable.

this is the name of a method within the PrintStream class. This method in
println particular prints the 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.

https://riptutorial.com/ 7
Element Purpose

"Hello, this is the String literal that is passed as a parameter, into the println method.
World!" The double quotation marks 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.

Note: Each statement in Java must end with a semicolon (;).

The method body and class body are then closed.

} // end of main function scope


} // end of class HelloWorld scope

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.

First, let's define our Team class:

public class Team {


Member member;
public Team(Member member) { // who is in this Team?
this.member = member; // one 'member' is in this Team!
}
}

Now, let's define our Member class:

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).

After putting it all together, and adding the getters and main method as discussed before, we
have:

https://riptutorial.com/ 8
public class Team {
Member member;
public Team(Member member) {
this.member = member;
}

// here's our main method


public static void main(String[] args) {
Member myMember = new Member("Aurieel", "light", 10, 1);
Team myTeam = new Team(myMember);
System.out.println(myTeam.member.getName());
System.out.println(myTeam.member.getType());
System.out.println(myTeam.member.getLevel());
System.out.println(myTeam.member.getRank());
}
}

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;
}

/* let's define our getter functions here */


public String getName() { // what is your name?
return this.name; // my name is ...
}

public String getType() { // what is your type?


return this.type; // my type is ...
}

public int getLevel() { // what is your level?


return this.level; // my level is ...
}

public int getRank() { // what is your rank?


return this.rank; // my rank is
}
}

Output:

Aurieel
light
10
1

Run on ideone

Once again, the main method inside the Test class is the entry point to our program. Without the
main method, we cannot tell the Java Virtual Machine (JVM) from where to begin execution of the

https://riptutorial.com/ 9
program.

1 - Because the HelloWorld class has little relation to the System class, it can only access public data.

Read Getting started with Java Language online: https://riptutorial.com/java/topic/84/getting-


started-with-java-language

https://riptutorial.com/ 10
Chapter 2: 2D Graphics in Java
Introduction
Graphics are visual images or designs on some surface, such as a wall, canvas, screen, paper, or
stone to inform, illustrate, or entertain. It includes: pictorial representation of data, as in computer-
aided design and manufacture, in typesetting and the graphic arts, and in educational and
recreational software. Images that are generated by a computer are called computer graphics.

The Java 2D API is powerful and complex. There are multiple ways to do 2D graphics in Java.

Examples
Example 1: Draw and Fill a Rectangle Using Java

This is an Example which print rectangle and fill color in the rectangle.

https://i.stack.imgur.com/dlC5v.jpg

Most methods of the Graphics class can be divided into two basic groups:

1. Draw and fill methods, enabling you to render basic shapes, text, and images
2. Attributes setting methods, which affect how that drawing and filling appears

Code Example: Let us start this with a little example of drawing a rectangle and filling color in it.
There we declare two classes, one class is MyPanel and other Class is Test. In class MyPanel we
use drawRect( ) & fillRect( ) mathods to draw rectangle and fill Color in it. We set the color by
setColor(Color.blue) method. In Second Class we Test our graphic which is Test Class we make a

https://riptutorial.com/ 11
Frame and put MyPanel with p=new MyPanel() object in it.By running Test Class we see a
Rectangle and a Blue Color Filled Rectangle.

First Class: MyPanel

import javax.swing.*;
import java.awt.*;
// MyPanel extends JPanel, which will eventually be placed in a JFrame
public class MyPanel extends JPanel {
// custom painting is performed by the paintComponent method
@Override
public void paintComponent(Graphics g){
// clear the previous painting
super.paintComponent(g);
// cast Graphics to Graphics2D
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.red); // sets Graphics2D color
// draw the rectangle
g2.drawRect(0,0,100,100); // drawRect(x-position, y-position, width, height)
g2.setColor(Color.blue);
g2.fillRect(200,0,100,100); // fill new rectangle with color blue
}
}

Second Class: Test

import javax.swing.;
import java.awt.;
public class Test { //the Class by which we display our rectangle
JFrame f;
MyPanel p;
public Test(){
f = new JFrame();
// get the content area of Panel.
Container c = f.getContentPane();
// set the LayoutManager
c.setLayout(new BorderLayout());
p = new MyPanel();
// add MyPanel object into container
c.add(p);
// set the size of the JFrame
f.setSize(400,400);
// make the JFrame visible
f.setVisible(true);
// sets close behavior; EXIT_ON_CLOSE invokes System.exit(0) on closing the JFrame
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public static void main(String args[ ]){


Test t = new Test();
}
}

For More Explanation about Border Layout:


https://docs.oracle.com/javase/tutorial/uiswing/layout/border.html

paintComponent( )

https://riptutorial.com/ 12
• It is a main method for painting
• By default, it first paints the background
• After that, it performs custom painting (drawing circle, rectangles etc.)

Graphic2D refers Graphic2D Class

Note: The Java 2D API enables you to easily perform the following tasks:

• Draw lines, rectangles and any other geometric shape.


• Fill those shapes with solid colors or gradients and textures.
• Draw text with options for fine control over the font and rendering process.
• Draw images, optionally applying filtering operations.
• Apply operations such as compositing and transforming during any of the above rendering
operations.

Example 2: Drawing and Filling Oval

import javax.swing.*;
import java.awt.*;

public class MyPanel extends JPanel {


@Override
public void paintComponent(Graphics g){
// clear the previous painting
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.blue);
g2.drawOval(0, 0, 20,20);
g2.fillOval(50,50,20,20);
}
}

g2.drawOval(int x,int y,int height, int width);


This method will draw an oval at specified x and y position with given height and width.

g2.fillOval(int x,int y,int height, int width); This method will fill an oval at specified x and y
position with given height and width.

Read 2D Graphics in Java online: https://riptutorial.com/java/topic/10127/2d-graphics-in-java

https://riptutorial.com/ 13
Chapter 3: Alternative Collections
Remarks
This topic about Java collections from guava, apache, eclipse: Multiset, Bag, Multimap, utils
function from this lib and so on.

Examples
Apache HashBag, Guava HashMultiset and Eclipse HashBag

A Bag/ultiset stores each object in the collection together with a count of occurrences. Extra
methods on the interface allow multiple copies of an object to be added or removed at once. JDK
analog is HashMap<T, Integer>, when values is count of copies this key.

Apache Commons
Type Guava GS Collections JDK
Collections

Order not
HashMultiset HashBag HashBag HashMap
defined

Sorted TreeMultiset TreeBag TreeBag TreeMap

Insertion-
LinkedHashMultiset - - LinkedHa
order

Concurrent
ConcurrentHashMultiset SynchronizedBag SynchronizedBag Collection
variant

Concurrent
- SynchronizedSortedBag SynchronizedSortedBag Collection
and sorted

Immutable
ImmutableMultiset UnmodifiableBag UnmodifiableBag Collection
collection

Immutable Collection
ImmutableSortedMultiset UnmodifiableSortedBag UnmodifiableSortedBag )
and sorted

Examples:

1. Using SynchronizedSortedBag from Apache:

// Parse text to separate words


String INPUT_TEXT = "Hello World! Hello All! Hi World!";
// Create Multiset
Bag bag = SynchronizedSortedBag.synchronizedBag(new

https://riptutorial.com/ 14
TreeBag(Arrays.asList(INPUT_TEXT.split(" "))));

// Print count words


System.out.println(bag); // print [1:All!,2:Hello,1:Hi,2:World!]- in natural (alphabet)
order
// Print all unique words
System.out.println(bag.uniqueSet()); // print [All!, Hello, Hi, World!]- in natural
(alphabet) order

// Print count occurrences of words


System.out.println("Hello = " + bag.getCount("Hello")); // print 2
System.out.println("World = " + bag.getCount("World!")); // print 2
System.out.println("All = " + bag.getCount("All!")); // print 1
System.out.println("Hi = " + bag.getCount("Hi")); // print 1
System.out.println("Empty = " + bag.getCount("Empty")); // print 0

// Print count all words


System.out.println(bag.size()); //print 6

// Print count unique words


System.out.println(bag.uniqueSet().size()); //print 4

2. Using TreeBag from Eclipse(GC):

// Parse text to separate words


String INPUT_TEXT = "Hello World! Hello All! Hi World!";
// Create Multiset
MutableSortedBag<String> bag = TreeBag.newBag(Arrays.asList(INPUT_TEXT.split(" ")));

// Print count words


System.out.println(bag); // print [All!, Hello, Hello, Hi, World!, World!]- in natural
order
// Print all unique words
System.out.println(bag.toSortedSet()); // print [All!, Hello, Hi, World!]- in natural
order

// Print count occurrences of words


System.out.println("Hello = " + bag.occurrencesOf("Hello")); // print 2
System.out.println("World = " + bag.occurrencesOf("World!")); // print 2
System.out.println("All = " + bag.occurrencesOf("All!")); // print 1
System.out.println("Hi = " + bag.occurrencesOf("Hi")); // print 1
System.out.println("Empty = " + bag.occurrencesOf("Empty")); // print 0

// Print count all words


System.out.println(bag.size()); //print 6

// Print count unique words


System.out.println(bag.toSet().size()); //print 4

3. Using LinkedHashMultiset from Guava:

// Parse text to separate words


String INPUT_TEXT = "Hello World! Hello All! Hi World!";
// Create Multiset
Multiset<String> multiset = LinkedHashMultiset.create(Arrays.asList(INPUT_TEXT.split("
")));

https://riptutorial.com/ 15
// Print count words
System.out.println(multiset); // print [Hello x 2, World! x 2, All!, Hi]- in predictable
iteration order
// Print all unique words
System.out.println(multiset.elementSet()); // print [Hello, World!, All!, Hi] - in
predictable iteration order

// Print count occurrences of words


System.out.println("Hello = " + multiset.count("Hello")); // print 2
System.out.println("World = " + multiset.count("World!")); // print 2
System.out.println("All = " + multiset.count("All!")); // print 1
System.out.println("Hi = " + multiset.count("Hi")); // print 1
System.out.println("Empty = " + multiset.count("Empty")); // print 0

// Print count all words


System.out.println(multiset.size()); //print 6

// Print count unique words


System.out.println(multiset.elementSet().size()); //print 4

More examples:
I. Apache Collection:

1. HashBag - order not defined


2. SynchronizedBag - concurrent and order not defined
3. SynchronizedSortedBag - - concurrent and sorted order
4. TreeBag - sorted order

II. GS / Eclipse Collection

5. MutableBag - order not defined


6. MutableSortedBag - sorted order

III. Guava

7. HashMultiset - order not defined


8. TreeMultiset - sorted order
9. LinkedHashMultiset - insertion order
10. ConcurrentHashMultiset - concurrent and order not defined

Multimap in Guava, Apache and Eclipse Collections

This multimap allows duplicate key-value pairs. JDK analogs are HashMap<K, List>, HashMap<K,
Set> and so on.

Key's Value's
Duplicate Analog key Analog value Guava Apache
order order

not Insertion-
yes HashMap ArrayList ArrayListMultimap MultiVal
defined order

https://riptutorial.com/ 16
Key's Value's
Duplicate Analog key Analog value Guava Apache
order order

MultiVal
not not multiVal
no HashMap HashSet HashMultimap HashMap<
defined defined
HashSet.

Multimaps.
not MultiVal
newMultimap(
sorted no HashMap TreeSet HashMap, Supplier
new Hash
defined TreeSet.
<TreeSet>)

MultiVal
Insertion- Insertion- multiVal
yes LinkedHashMap ArrayList LinkedListMultimap
order order LinkedH
ArrayLis

MultiVal
Insertion- Insertion- multiVal
no LinkedHashMap LinkedHashSet LinkedHashMultimap LinkedHa
order order
LinkedHa

MultiVal
multiVal
sorted sorted no TreeMap TreeSet TreeMultimap TreeMap<
Set>(),T

Examples using Multimap

Task: Parse "Hello World! Hello All! Hi World!" string to separate words and print all indexes of
every word using MultiMap (for example, Hello=[0, 2], World!=[1, 5] and so on)

1. MultiValueMap from Apache

String INPUT_TEXT = "Hello World! Hello All! Hi World!";


// Parse text to words and index
List<String> words = Arrays.asList(INPUT_TEXT.split(" "));
// Create Multimap
MultiMap<String, Integer> multiMap = new MultiValueMap<String, Integer>();

// Fill Multimap
int i = 0;
for(String word: words) {
multiMap.put(word, i);
i++;
}

// Print all words


System.out.println(multiMap); // print {Hi=[4], Hello=[0, 2], World!=[1, 5], All!=[3]} -
in random orders
// Print all unique words
System.out.println(multiMap.keySet()); // print [Hi, Hello, World!, All!] - in random
orders

// Print all indexes


System.out.println("Hello = " + multiMap.get("Hello")); // print [0, 2]
System.out.println("World = " + multiMap.get("World!")); // print [1, 5]
System.out.println("All = " + multiMap.get("All!")); // print [3]

https://riptutorial.com/ 17
System.out.println("Hi = " + multiMap.get("Hi")); // print [4]
System.out.println("Empty = " + multiMap.get("Empty")); // print null

// Print count unique words


System.out.println(multiMap.keySet().size()); //print 4

2. HashBiMap from GS / Eclipse Collection

String[] englishWords = {"one", "two", "three","ball","snow"};


String[] russianWords = {"jeden", "dwa", "trzy", "kula", "snieg"};

// Create Multiset
MutableBiMap<String, String> biMap = new HashBiMap(englishWords.length);
// Create English-Polish dictionary
int i = 0;
for(String englishWord: englishWords) {
biMap.put(englishWord, russianWords[i]);
i++;
}

// Print count words


System.out.println(biMap); // print {two=dwa, ball=kula, one=jeden, snow=snieg,
three=trzy} - in random orders
// Print all unique words
System.out.println(biMap.keySet()); // print [snow, two, one, three, ball] - in random
orders
System.out.println(biMap.values()); // print [dwa, kula, jeden, snieg, trzy] - in
random orders

// Print translate by words


System.out.println("one = " + biMap.get("one")); // print one = jeden
System.out.println("two = " + biMap.get("two")); // print two = dwa
System.out.println("kula = " + biMap.inverse().get("kula")); // print kula = ball
System.out.println("snieg = " + biMap.inverse().get("snieg")); // print snieg = snow
System.out.println("empty = " + biMap.get("empty")); // print empty = null

// Print count word's pair


System.out.println(biMap.size()); //print 5

3. HashMultiMap from Guava

String INPUT_TEXT = "Hello World! Hello All! Hi World!";


// Parse text to words and index
List<String> words = Arrays.asList(INPUT_TEXT.split(" "));
// Create Multimap
Multimap<String, Integer> multiMap = HashMultimap.create();

// Fill Multimap
int i = 0;
for(String word: words) {
multiMap.put(word, i);
i++;
}

// Print all words


System.out.println(multiMap); // print {Hi=[4], Hello=[0, 2], World!=[1, 5], All!=[3]} -
keys and values in random orders
// Print all unique words

https://riptutorial.com/ 18
System.out.println(multiMap.keySet()); // print [Hi, Hello, World!, All!] - in random
orders

// Print all indexes


System.out.println("Hello = " + multiMap.get("Hello")); // print [0, 2]
System.out.println("World = " + multiMap.get("World!")); // print [1, 5]
System.out.println("All = " + multiMap.get("All!")); // print [3]
System.out.println("Hi = " + multiMap.get("Hi")); // print [4]
System.out.println("Empty = " + multiMap.get("Empty")); // print []

// Print count all words


System.out.println(multiMap.size()); //print 6

// Print count unique words


System.out.println(multiMap.keySet().size()); //print 4

Nore examples:
I. Apache Collection:

1. MultiValueMap
2. MultiValueMapLinked
3. MultiValueMapTree

II. GS / Eclipse Collection

1. FastListMultimap
2. HashBagMultimap
3. TreeSortedSetMultimap
4. UnifiedSetMultimap

III. Guava

1. HashMultiMap
2. LinkedHashMultimap
3. LinkedListMultimap
4. TreeMultimap
5. ArrayListMultimap

Compare operation with collections - Create collections

Compare operation with collections - Create collections

1. Create List
Description JDK guava gs-collections

Create
new ArrayList<>() Lists.newArrayList() FastList.newList()
empty list

Create list Arrays.asList("1", "2", FastList.newListWith("1",


Lists.newArrayList("1", "2", "3")
"3") "2", "3")

https://riptutorial.com/ 19
Description JDK guava gs-collections

from values

Create list
with
new ArrayList<>(100) Lists.newArrayListWithCapacity(100) FastList.newList(100)
capacity =
100

Create list
new
from any ArrayList<>(collection)
Lists.newArrayList(collection) FastList.newList(collecti
collectin

Create list
from any - Lists.newArrayList(iterable) FastList.newList(iterable
Iterable

Create list
- Lists.newArrayList(iterator) -
from Iterator

Create list
Arrays.asList(array) Lists.newArrayList(array) FastList.newListWith(arra
from array

Create list
FastList.newWithNValues(1
using - - () -> "1")
factory

Examples:

System.out.println("createArrayList start");
// Create empty list
List<String> emptyGuava = Lists.newArrayList(); // using guava
List<String> emptyJDK = new ArrayList<>(); // using JDK
MutableList<String> emptyGS = FastList.newList(); // using gs

// Create list with 100 element


List < String > exactly100 = Lists.newArrayListWithCapacity(100); // using guava
List<String> exactly100JDK = new ArrayList<>(100); // using JDK
MutableList<String> empty100GS = FastList.newList(100); // using gs

// Create list with about 100 element


List<String> approx100 = Lists.newArrayListWithExpectedSize(100); // using guava
List<String> approx100JDK = new ArrayList<>(115); // using JDK
MutableList<String> approx100GS = FastList.newList(115); // using gs

// Create list with some elements


List<String> withElements = Lists.newArrayList("alpha", "beta", "gamma"); // using guava
List<String> withElementsJDK = Arrays.asList("alpha", "beta", "gamma"); // using JDK
MutableList<String> withElementsGS = FastList.newListWith("alpha", "beta", "gamma"); //
using gs

System.out.println(withElements);
System.out.println(withElementsJDK);
System.out.println(withElementsGS);

https://riptutorial.com/ 20
// Create list from any Iterable interface (any collection)
Collection<String> collection = new HashSet<>(3);
collection.add("1");
collection.add("2");
collection.add("3");

List<String> fromIterable = Lists.newArrayList(collection); // using guava


List<String> fromIterableJDK = new ArrayList<>(collection); // using JDK
MutableList<String> fromIterableGS = FastList.newList(collection); // using gs

System.out.println(fromIterable);
System.out.println(fromIterableJDK);
System.out.println(fromIterableGS);
/* Attention: JDK create list only from Collection, but guava and gs can create list from
Iterable and Collection */

// Create list from any Iterator


Iterator<String> iterator = collection.iterator();
List<String> fromIterator = Lists.newArrayList(iterator); // using guava
System.out.println(fromIterator);

// Create list from any array


String[] array = {"4", "5", "6"};
List<String> fromArray = Lists.newArrayList(array); // using guava
List<String> fromArrayJDK = Arrays.asList(array); // using JDK
MutableList<String> fromArrayGS = FastList.newListWith(array); // using gs
System.out.println(fromArray);
System.out.println(fromArrayJDK);
System.out.println(fromArrayGS);

// Create list using fabric


MutableList<String> fromFabricGS = FastList.newWithNValues(10, () ->
String.valueOf(Math.random())); // using gs
System.out.println(fromFabricGS);

System.out.println("createArrayList end");

2 Create Set
Description JDK guava gs-collections

Create
new HashSet<>() Sets.newHashSet() UnifiedSet.newSet()
empty set

new
Creatre set HashSet<>(Arrays.asList("alpha", Sets.newHashSet("alpha", UnifiedSet.newSetWith("a
from values "beta", "gamma") "beta", "gamma")
"beta", "gamma"))

Create set
from any new HashSet<>(collection) Sets.newHashSet(collection) UnifiedSet.newSet(collec
collections

Create set
from any - Sets.newHashSet(iterable) UnifiedSet.newSet(iterab
Iterable

Create set - Sets.newHashSet(iterator) -

https://riptutorial.com/ 21
Description JDK guava gs-collections

from any
Iterator

Create set new


Sets.newHashSet(array) UnifiedSet.newSetWith(ar
from Array HashSet<>(Arrays.asList(array))

Examples:

System.out.println("createHashSet start");
// Create empty set
Set<String> emptyGuava = Sets.newHashSet(); // using guava
Set<String> emptyJDK = new HashSet<>(); // using JDK
Set<String> emptyGS = UnifiedSet.newSet(); // using gs

// Create set with 100 element


Set<String> approx100 = Sets.newHashSetWithExpectedSize(100); // using guava
Set<String> approx100JDK = new HashSet<>(130); // using JDK
Set<String> approx100GS = UnifiedSet.newSet(130); // using gs

// Create set from some elements


Set<String> withElements = Sets.newHashSet("alpha", "beta", "gamma"); // using guava
Set<String> withElementsJDK = new HashSet<>(Arrays.asList("alpha", "beta", "gamma")); //
using JDK
Set<String> withElementsGS = UnifiedSet.newSetWith("alpha", "beta", "gamma"); // using gs

System.out.println(withElements);
System.out.println(withElementsJDK);
System.out.println(withElementsGS);

// Create set from any Iterable interface (any collection)


Collection<String> collection = new ArrayList<>(3);
collection.add("1");
collection.add("2");
collection.add("3");

Set<String> fromIterable = Sets.newHashSet(collection); // using guava


Set<String> fromIterableJDK = new HashSet<>(collection); // using JDK
Set<String> fromIterableGS = UnifiedSet.newSet(collection); // using gs

System.out.println(fromIterable);
System.out.println(fromIterableJDK);
System.out.println(fromIterableGS);
/* Attention: JDK create set only from Collection, but guava and gs can create set from
Iterable and Collection */

// Create set from any Iterator


Iterator<String> iterator = collection.iterator();
Set<String> fromIterator = Sets.newHashSet(iterator); // using guava
System.out.println(fromIterator);

// Create set from any array


String[] array = {"4", "5", "6"};
Set<String> fromArray = Sets.newHashSet(array); // using guava
Set<String> fromArrayJDK = new HashSet<>(Arrays.asList(array)); // using JDK
Set<String> fromArrayGS = UnifiedSet.newSetWith(array); // using gs
System.out.println(fromArray);
System.out.println(fromArrayJDK);

https://riptutorial.com/ 22
System.out.println(fromArrayGS);

System.out.println("createHashSet end");

3 Create Map
Description JDK guava gs-collections

Create new
Maps.newHashMap() UnifiedMap.newMap()
empty map HashMap<>()

Create map
with new
Maps.newHashMapWithExpectedSize(100) UnifiedMap.newMap(130)
capacity = HashMap<>(130)

130

Create map
new
from other HashMap<>(map)
Maps.newHashMap(map) UnifiedMap.newMap(map)
map

Create map UnifiedMap.newWithKeysValues("1",


- - "a", "2", "b")
from keys

Examples:

System.out.println("createHashMap start");
// Create empty map
Map<String, String> emptyGuava = Maps.newHashMap(); // using guava
Map<String, String> emptyJDK = new HashMap<>(); // using JDK
Map<String, String> emptyGS = UnifiedMap.newMap(); // using gs

// Create map with about 100 element


Map<String, String> approx100 = Maps.newHashMapWithExpectedSize(100); // using guava
Map<String, String> approx100JDK = new HashMap<>(130); // using JDK
Map<String, String> approx100GS = UnifiedMap.newMap(130); // using gs

// Create map from another map


Map<String, String> map = new HashMap<>(3);
map.put("k1","v1");
map.put("k2","v2");
Map<String, String> withMap = Maps.newHashMap(map); // using guava
Map<String, String> withMapJDK = new HashMap<>(map); // using JDK
Map<String, String> withMapGS = UnifiedMap.newMap(map); // using gs

System.out.println(withMap);
System.out.println(withMapJDK);
System.out.println(withMapGS);

// Create map from keys


Map<String, String> withKeys = UnifiedMap.newWithKeysValues("1", "a", "2", "b");
System.out.println(withKeys);

System.out.println("createHashMap end");

More examples: CreateCollectionTest

https://riptutorial.com/ 23
1. CollectionCompare
2. CollectionSearch
3. JavaTransform

Read Alternative Collections online: https://riptutorial.com/java/topic/2958/alternative-collections

https://riptutorial.com/ 24
Chapter 4: Annotations
Introduction
In Java, an annotation is a form of syntactic metadata that can be added to Java source code. It
provides data about a program that is not part of the program itself. Annotations have no direct
effect on the operation of the code they annotate. Classes, methods, variables, parameters and
packages are allowed to be annotated.

Syntax
• @AnnotationName // 'Marker annotation' (no parameters)
• @AnnotationName(someValue) // sets parameter with the name 'value'
• @AnnotationName(param1 = value1) // named parameter
• @AnnotationName(param1 = value1, param2 = value2) // multiple named parameters
• @AnnotationName(param1 = {1, 2, 3}) // named array parameter
• @AnnotationName({value1}) // array with single element as parameter with the name 'value'

Remarks

Parameter types
Only constant expressions of following types are allowed for parameters, as well as arrays of
these types:

• String
• Class
• primitive types
• Enum types
• Annotation Types

Examples
Built-in annotations

The Standard Edition of Java comes with some annotations predefined. You do not need to define
them by yourself and you can use them immediately. They allow the compiler to enable some
fundamental checking of methods, classes and code.

@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

https://riptutorial.com/ 25
kind of method, the compiler will throw an error.

Concrete superclass

public class Vehicle {


public void drive() {
System.out.println("I am driving");
}
}

class Car extends Vehicle {


// Fine
@Override
public void drive() {
System.out.prinln("Brrrm, brrm");
}
}

Abstract class

abstract class Animal {


public abstract void makeNoise();
}

class Dog extends Animal {


// Fine
@Override
public void makeNoise() {
System.out.prinln("Woof");
}
}

Does not work

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 {
public void drive() {
System.out.println("I am driving");
}

https://riptutorial.com/ 26
}

class Car extends Vehicle {


// Compiler error. "dirve" is not the correct method name to override.
@Override
public void dirve() {
System.out.prinln("Brrrm, brrm");
}
}

Note that the meaning of @Override has changed over time:

• 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 API is flawed and is impractical to fix,

• usage of the API is likely to lead to errors,

• the API has been superseded by another API,

• the API is obsolete,

• the API is experimental and is subject to incompatible changes,

• or any combination of the above.

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
}

public void quickThreadSafeMethod() {


// client code should use this instead
}
}

@SuppressWarnings

https://riptutorial.com/ 27
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.

This annotation can be applied to a whole class, method or line. It takes the category of warning
as a parameter.

@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:

ComplexAlgorithm algorithm = new ComplexAlgorithm();


@SuppressWarnings("deprecation") algoritm.slowUnthreadSafeMethod();
// we marked this method deprecated in an example above

@SuppressWarnings("unsafe") List<Integer> list = getUntypeSafeList();


// old library returns, non-generic List containing only integers

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:

private static <T> void generatesVarargsWarning(T... lists) {

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 {

https://riptutorial.com/ 28
public boolean check(Trade t);
}

@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}

Runtime annotation checks via reflection

Java's Reflection API allows the programmer to perform various checks and operations on class
fields, methods and annotations during runtime. However, in order for an annotation to be at all
visible at runtime, the RetentionPolicy must be changed to RUNTIME, as demonstrated in the
example below:

@interface MyDefaultAnnotation {

@Retention(RetentionPolicy.RUNTIME)
@interface MyRuntimeVisibleAnnotation {

public class AnnotationAtRuntimeTest {

@MyDefaultAnnotation
static class RuntimeCheck1 {
}

@MyRuntimeVisibleAnnotation
static class RuntimeCheck2 {
}

public static void main(String[] args) {


Annotation[] annotationsByType = RuntimeCheck1.class.getAnnotations();
Annotation[] annotationsByType2 = RuntimeCheck2.class.getAnnotations();

System.out.println("default retention: " + Arrays.toString(annotationsByType));


System.out.println("runtime retention: " + Arrays.toString(annotationsByType2));
}
}

Defining annotation types

Annotation types are defined with @interface. Parameters are defined similar to methods of a
regular interface.

@interface MyAnnotation {
String param1();
boolean param2();
int[] param3(); // array parameter
}

https://riptutorial.com/ 29
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.

@Target
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)
ANNOTATION_TYPE annotation types @interface MyAnnotation

@MyAnnotation
CONSTRUCTOR constructors public MyClass() {}

@XmlAttribute
FIELD fields, enum constants private int count;

for (@LoopVariable int i = 0; i < 100;


variable declarations i++) {
LOCAL_VARIABLE @Unused
inside methods
String resultVariable;

https://riptutorial.com/ 30
ElementType target example usage on target element

package (in package- @Deprecated


PACKAGE package very.old;
info.java)

@XmlElement
METHOD methods public int getCount() {...}

public Rectangle(
@NamedArg("width") double
width,
method/constructor
PARAMETER @NamedArg("height") double
parameters height) {
...
}

classes, interfaces, @XmlRootElement


TYPE public class Report {}
enums

Java SE 8
ElementType target example usage on target element

Type parameter public <@MyAnnotation T> void f(T t)


TYPE_PARAMETER {}
declarations

Object o = "42";
TYPE_USE Use of a type String s = (@MyAnnotation String) o;

@Retention
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 {

https://riptutorial.com/ 31
// 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
SOURCE
files. The annotation can be 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 annotation in the documentation.

@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.

Getting Annotation values at run-time

You can fetch the current properties of the Annotation by using Reflection to fetch the Method or
Field or Class which has an Annotation applied to it, and then fetching the desired properties.

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
String key() default "foo";

https://riptutorial.com/ 32
String value() default "bar";
}

class AnnotationExample {
// Put the Annotation on the method, but leave the defaults
@MyAnnotation
public void testDefaults() throws Exception {
// Using reflection, get the public method "testDefaults", which is this method with
no args
Method method = AnnotationExample.class.getMethod("testDefaults", null);

// Fetch the Annotation that is of type MyAnnotation from the Method


MyAnnotation annotation = (MyAnnotation)method.getAnnotation(MyAnnotation.class);

// Print out the settings of the Annotation


print(annotation);
}

//Put the Annotation on the method, but override the settings


@MyAnnotation(key="baz", value="buzz")
public void testValues() throws Exception {
// Using reflection, get the public method "testValues", which is this method with no
args
Method method = AnnotationExample.class.getMethod("testValues", null);

// Fetch the Annotation that is of type MyAnnotation from the Method


MyAnnotation annotation = (MyAnnotation)method.getAnnotation(MyAnnotation.class);

// Print out the settings of the Annotation


print(annotation);
}

public void print(MyAnnotation annotation) {


// Fetch the MyAnnotation 'key' & 'value' properties, and print them out
System.out.println(annotation.key() + " = " + annotation.value());
}

public static void main(String[] args) {


AnnotationExample example = new AnnotationExample();
try {
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);
}
}
}

The output will be

foo = bar
baz = buzz

Repeating Annotations

https://riptutorial.com/ 33
Until Java 8, two instances of the same annotation could not be applied to a single element. The
standard workaround was to use a container annotation holding an array of some other
annotation:

// 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
}
}
}

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 container:

@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
}
}

https://riptutorial.com/ 34
}

Inherited Annotations

By default class annotations do not apply to types extending them. This can be changed by adding
the @Inherited annotation to the annotation definition

Example
Consider the following 2 Annotations:

@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface InheritedAnnotationType {
}

and

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface UninheritedAnnotationType {
}

If three classes are annotated like this:

@UninheritedAnnotationType
class A {
}

@InheritedAnnotationType
class B extends A {
}

class C extends B {
}

running this code

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));
System.out.println(new B().getClass().getAnnotation(UninheritedAnnotationType.class));
System.out.println(new C().getClass().getAnnotation(UninheritedAnnotationType.class));

will print a result similar to this (depending on the packages of the annotation):

null
@InheritedAnnotationType()
@InheritedAnnotationType()

https://riptutorial.com/ 35
_________________________________
@UninheritedAnnotationType()
null
null

Note that annotations can only be inherited from classes, not interfaces.

Compile time processing using annotation processor

This example demonstrates how to do compile time checking of an annotated element.

The annotation
The @Setter annotation is a marker can be applied to methods. The annotation will be discarded
during compilation not be available afterwards.

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;

https://riptutorial.com/ 36
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 {

private Messager messager;

@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);

for (Element element : annotatedElements) {


if (element.getKind() == ElementKind.METHOD) {
// only handle methods as targets
checkMethod((ExecutableElement) element);
}
}

// don't claim annotations to allow other processors to process them


return false;
}

private void checkMethod(ExecutableElement method) {


// check for valid name
String name = method.getSimpleName().toString();
if (!name.startsWith("set")) {
printError(method, "setter name must start with \"set\"");
} else if (name.length() == 3) {
printError(method, "the method name must contain more than just \"set\"");
} else if (Character.isLowerCase(name.charAt(3))) {
if (method.getParameters().size() != 1) {
printError(method, "character following \"set\" must be upper case");
}
}

// check, if setter is public


if (!method.getModifiers().contains(Modifier.PUBLIC)) {
printError(method, "setter must be public");
}

// check, if method is static


if (method.getModifiers().contains(Modifier.STATIC)) {
printError(method, "setter must not be static");
}
}

private void printError(Element element, String message) {


messager.printMessage(Diagnostic.Kind.ERROR, message, element);
}

@Override
public void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);

https://riptutorial.com/ 37
// get messager for printing errors
messager = processingEnvironment.getMessager();
}

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

We'll assume the jar file is called AnnotationProcessor.jar below.

Example annotated class


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;

public class AnnotationProcessorTest {

@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

javac -cp AnnotationProcessor.jar AnnotationProcessorTest.java

https://riptutorial.com/ 38
yields the following output

AnnotationProcessorTest.java:6: error: setter must be public


private void setValue(String value) {}
^
AnnotationProcessorTest.java:12: error: setter name must start with "set"
public static void main(String[] args) {}
^
2 errors

instead of compiling normally. No .class file is created.

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:

1. go to Project Properties > Build > Compiling

2. add check marks for Enable Annotation Processing and Enable Annotation Processing in
Editor

3. click Add next to the annotation processor list

4. in the popup that appears enter the fully qualified class name of the annotation processor
and click Ok.

Result

https://riptutorial.com/ 39
The idea behind Annotations

The Java Language Specification describes Annotations as follows:

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.

This topic aims to provide a comprehensive overview of:

• How to define your own Annotations?

• What Annotations does the Java Language provide?

• How are Annotations used in practice?

Annotations for 'this' and receiver parameters

When Java annotations were first introduced there was no provision for annotating the target of an
instance method or the hidden constructor parameter for an inner classes constructor. This was
remedied in Java 8 with addition of receiver parameter declarations; see JLS 8.4.1.

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:

public class Outer {


public class Inner {
public Inner (Outer this) {

https://riptutorial.com/ 40
// ...
}
public void doIt(Inner this) {
// ...
}
}
}

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:

public class MyResource extends Closeable {


public void update(@IsOpen MyResource this, int value) {
// ...
}

public void close() {


// ...
}
}

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.

Add multiple annotation values

An Annotation parameter can accept multiple values if it is defined as an array. For example the
standard annotation @SuppressWarnings is defined like this:

public @interface SuppressWarnings {


String[] value();
}

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")

Read Annotations online: https://riptutorial.com/java/topic/157/annotations

https://riptutorial.com/ 41
Chapter 5: Apache Commons Lang
Examples
Implement equals() method

To implement the equals method of an object easily you could use the EqualsBuilder class.

Selecting the fields:

@Override
public boolean equals(Object obj) {

if(!(obj instanceof MyClass)) {


return false;
}
MyClass theOther = (MyClass) obj;

EqualsBuilder builder = new EqualsBuilder();


builder.append(field1, theOther.field1);
builder.append(field2, theOther.field2);
builder.append(field3, theOther.field3);

return builder.isEquals();
}

Using reflection:

@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj, false);
}

the boolean parameter is to indicates if the equals should check transient fields.

Using reflection avoiding some fields:

@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj, "field1", "field2");
}

Implement hashCode() method

To implement the hashCode method of an object easily you could use the HashCodeBuilder class.

Selecting the fields:

@Override
public int hashCode() {

https://riptutorial.com/ 42
HashCodeBuilder builder = new HashCodeBuilder();
builder.append(field1);
builder.append(field2);
builder.append(field3);

return builder.hashCode();
}

Using reflection:

@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, false);
}

the boolean parameter indicates if it should use transient fields.

Using reflection avoiding some fields:

@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, "field1", "field2");
}

Implement toString() method

To implement the toString method of an object easily you could use the ToStringBuilder class.

Selecting the fields:

@Override
public String toString() {

ToStringBuilder builder = new ToStringBuilder(this);


builder.append(field1);
builder.append(field2);
builder.append(field3);

return builder.toString();
}

Example result:

ar.com.jonat.lang.MyClass@dd7123[<null>,0,false]

Explicitly giving names to the fields:

@Override
public String toString() {

ToStringBuilder builder = new ToStringBuilder(this);


builder.append("field1",field1);

https://riptutorial.com/ 43
builder.append("field2",field2);
builder.append("field3",field3);

return builder.toString();
}

Example result:

ar.com.jonat.lang.MyClass@dd7404[field1=<null>,field2=0,field3=false]

You could change the style via parameter:

@Override
public String toString() {

ToStringBuilder builder = new ToStringBuilder(this,


ToStringStyle.MULTI_LINE_STYLE);
builder.append("field1", field1);
builder.append("field2", field2);
builder.append("field3", field3);

return builder.toString();
}

Example result:

ar.com.bna.lang.MyClass@ebbf5c[
field1=<null>
field2=0
field3=false
]

There are some styles, for example JSON, no Classname, short, etc ...

Via reflection:

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}

You could also indicate the style:

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}

Read Apache Commons Lang online: https://riptutorial.com/java/topic/3338/apache-commons-


lang

https://riptutorial.com/ 44
Chapter 6: AppDynamics and TIBCO
BusinessWorks Instrumentation for Easy
Integration
Introduction
As AppDynamics aims to provide a way to measure application performance, speed of
development, delivery (deployment) of applications is an essential factor in making DevOps efforts
a true success. Monitoring a TIBCO BW application with AppD is generally simple and not time
consuming but when deploying large sets of applications rapid instrumentation is key. This guide
shows how to instrument all of your BW applications in a single step without modifying each
application before deploying.

Examples
Example of Instrumentation of all BW Applications in a Single Step for
Appdynamics

1. Locate and open your TIBCO BW bwengine.tra file typlically under


TIBCO_HOME/bw/5.12/bin/bwengine.tra (Linux environment)

2. Look for the line that states:

*** Common variables. Modify these only. ***


3. Add the following line right after that section tibco.deployment=%tibco.deployment%

4. Go to the end of the file and add (replace ? with your own values as needed or remove the
flag that does not apply): java.extended.properties=-
javaagent:/opt/appd/current/appagent/javaagent.jar -Dappdynamics.http.proxyHost=? -
Dappdynamics.http.proxyPort=? -Dappdynamics.agent.applicationName=? -
Dappdynamics.agent.tierName=? -Dappdynamics.agent.nodeName=%tibco.deployment% -
Dappdynamics.controller.ssl.enabled=? -Dappdynamics.controller.sslPort=? -
Dappdynamics.agent.logs.dir=? -Dappdynamics.agent.runtime.dir=? -
Dappdynamics.controller.hostName=? -Dappdynamics.controller.port=? -
Dappdynamics.agent.accountName=? -Dappdynamics.agent.accountAccessKey=?

5. Save file and redeploy. All your applications should now be instrumented automatically at
deployment time.

Read AppDynamics and TIBCO BusinessWorks Instrumentation for Easy Integration online:
https://riptutorial.com/java/topic/10602/appdynamics-and-tibco-businessworks-instrumentation-for-

https://riptutorial.com/ 45
easy-integration

https://riptutorial.com/ 46
Chapter 7: Applets
Introduction
Applets have been part of Java since its official release and have been used to teach Java and
programming for a number of years.

Recent years have seen an active push to move away from Applets and other browser plugins,
with some browsers blocking them or actively not supporting them.

In 2016, Oracle announced their plans to deprecate the plugin, Moving to a Plugin-Free Web

Newer and better APIs are now available

Remarks
An applet is a Java application that normally runs inside a web browser. The basic idea is to
interact with the user without the need to interact with the server and transfer information. This
concept was very successful around the year 2000 when internet communication was slow and
expensive.

An applet offers five methods to control their life cycle.

method name description

init() is called once when the applet is loaded

destroy() is called once when the applet gets removed from memory

start() is called whenever the applet gets visible

stop() is called whenever the applet get overlapped by other windows

paint() is called when needed or manually triggered by calling repaint()

Examples
Minimal Applet

A very simple applet draws a rectangle and prints a string something on the screen.

public class MyApplet extends JApplet{

private String str = "StackOverflow";

@Override

https://riptutorial.com/ 47
public void init() {
setBackground(Color.gray);
}
@Override
public void destroy() {}
@Override
public void start() {}
@Override
public void stop() {}
@Override
public void paint(Graphics g) {
g.setColor(Color.yellow);
g.fillRect(1,1,300,150);
g.setColor(Color.red);
g.setFont(new Font("TimesRoman", Font.PLAIN, 48));
g.drawString(str, 10, 80);
}
}

The main class of an applet extends from javax.swing.JApplet.

Java SE 1.2

Before Java 1.2 and the introduction of the swing API applets had extended from
java.applet.Applet.

Applets don't require a main method. The entry point is controlled by the life cycle. To use them,
they need to be embedded in a HTML document. This is also the point where their size is defined.

<html>
<head></head>
<body>
<applet code="MyApplet.class" width="400" height="200"></applet>
</body>
</html>

Creating a GUI

Applets could easily be used to create a GUI. They act like a Container and have an add() method
that takes any awt or swing component.

public class MyGUIApplet extends JApplet{

private JPanel panel;


private JButton button;
private JComboBox<String> cmbBox;
private JTextField textField;

@Override
public void init(){
panel = new JPanel();
button = new JButton("ClickMe!");
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent ae) {
if(((String)cmbBox.getSelectedItem()).equals("greet")) {

https://riptutorial.com/ 48
JOptionPane.showMessageDialog(null,"Hello " + textField.getText());
} else {
JOptionPane.showMessageDialog(null,textField.getText() + " stinks!");
}
}
});
cmbBox = new JComboBox<>(new String[]{"greet", "offend"});
textField = new JTextField("John Doe");
panel.add(cmbBox);
panel.add(textField);
panel.add(button);
add(panel);
}
}

Open links from within the applet

You can use the method getAppletContext() to get an AppletContext object that allows you to
request the browser to open a link. For this you use the method showDocument(). Its second
parameter tells the browser to use a new window _blank or the one that shows the applet _self.

public class MyLinkApplet extends JApplet{


@Override
public void init(){
JButton button = new JButton("ClickMe!");
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent ae) {
AppletContext a = getAppletContext();
try {
URL url = new URL("http://stackoverflow.com/");
a.showDocument(url,"_blank");
} catch (Exception e) { /* omitted for brevity */ }
}
});
add(button);
}
}

Loading images, audio and other resources

Java applets are able to load different resources. But since they are running in the web browser of
the client you need to make sure that these resources are accessible. Applets are not able to
access client resources as the local file system.

If you want to load resources from the same URL the Applet is stored you can use the method
getCodeBase() to retrieve the base URL. To load resources, applets offer the methods getImage()
and getAudioClip() to load images or audio files.

Load and show an image

https://riptutorial.com/ 49
public class MyImgApplet extends JApplet{

private Image img;

@Override
public void init(){
try {
img = getImage(new URL("http://cdn.sstatic.net/stackexchange/img/logos/so/so-
logo.png"));
} catch (MalformedURLException e) { /* omitted for brevity */ }
}
@Override
public void paint(Graphics g) {
g.drawImage(img, 0, 0, this);
}
}

Load and play an audio file

public class MyAudioApplet extends JApplet{

private AudioClip audioClip;

@Override
public void init(){
try {
audioClip = getAudioClip(new URL("URL/TO/AN/AUDIO/FILE.WAV"));
} catch (MalformedURLException e) { /* omitted for brevity */ }
}
@Override
public void start() {
audioClip.play();
}
@Override
public void stop(){
audioClip.stop();
}
}

Load and display a text file

public class MyTextApplet extends JApplet{


@Override
public void init(){
JTextArea textArea = new JTextArea();
JScrollPane sp = new JScrollPane(textArea);
add(sp);
// load text
try {
URL url = new URL("http://www.textfiles.com/fun/quotes.txt");
InputStream in = url.openStream();
BufferedReader bf = new BufferedReader(new InputStreamReader(in));

https://riptutorial.com/ 50
String line = "";
while((line = bf.readLine()) != null) {
textArea.append(line + "\n");
}
} catch(Exception e) { /* omitted for brevity */ }
}
}

Read Applets online: https://riptutorial.com/java/topic/5503/applets

https://riptutorial.com/ 51
Chapter 8: Arrays
Introduction
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.

Syntax
• ArrayType[] myArray; // Declaring arrays
• ArrayType myArray[]; // Another valid syntax (less commonly used and discouraged)
• ArrayType[][][] myArray; // Declaring multi-dimensional jagged arrays (repeat []s)
• ArrayType myVar = myArray[index]; // Accessing (reading) element at index
• myArray[index] = value; // Assign value to position index of array
• ArrayType[] myArray = new ArrayType[arrayLength]; // Array initialization syntax
• int[] ints = {1, 2, 3}; // Array initialization syntax with values provided, length is inferred
from the number of provided values: {[value1[, value2]*]}
• new int[]{4, -5, 6} // Can be used as argument, without a local variable
• int[] ints = new int[3]; // same as {0, 0, 0}
• int[][] ints = {{1, 2}, {3}, null};// Multi-dimensional array initialization. int[] extends
Object (and so does anyType[]) so null is a valid value.

Parameters

Parameter Details

Type of the array. This can be primitive (int, long, byte) or Objects (String,
ArrayType
MyObject, etc).

index Index refers to the position of a certain Object in an array.

Every array, when being created, needs a set length specified. This is either
length done when creating an empty array (new int[3]) or implied when specifying
values ({1, 2, 3}).

Examples
Creating and Initializing Arrays

Basic cases

https://riptutorial.com/ 52
int[] numbers1 = new int[3]; // Array for 3 int values, default value is 0
int[] numbers2 = { 1, 2, 3 }; // Array literal of 3 int values
int[] numbers3 = new int[] { 1, 2, 3 }; // Array of 3 int values initialized
int[][] numbers4 = { { 1, 2 }, { 3, 4, 5 } }; // Jagged array literal
int[][] numbers5 = new int[5][]; // Jagged array, one dimension 5 long
int[][] numbers6 = new int[5][4]; // Multidimensional array: 5x4

Arrays may be created using any primitive or reference type.

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

UserDefinedClass[] udType = new UserDefinedClass[5];

Arrays, Collections, and Streams


Java SE 1.2

// Parameters require objects, not primitives

// Auto-boxing happening for int 127 here


Integer[] initial = { 127, Integer.valueOf( 42 ) };
List<Integer> toList = Arrays.asList( initial ); // Fixed size!

// Note: Works with all collections


Integer[] fromCollection = toList.toArray( new Integer[toList.size()] );

//Java doesn't allow you to create an array of a parameterized type


List<String>[] list = new ArrayList<String>[2]; // Compilation error!

Java SE 8

// Streams - JDK 8+
Stream<Integer> toStream = Arrays.stream( initial );
Integer[] fromStream = toStream.toArray( Integer[]::new );

Intro
An array is a data structure that holds a fixed number of primitive values or references to object
instances.

https://riptutorial.com/ 53
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:

int size = 42;


int[] array = new int[size];

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.

If the array is of a primitive type, i.e.

int[] array1 = { 1,2,3 };


int[] array2 = new int[10];

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).

If the array type is an object reference, as in

SomeClassOrInterface[] array = new SomeClassOrInterface[10];

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:

long size = 23L;


int[] array = new int[size]; // Compile-time error:
// incompatible types: possible lossy conversion from
// long to int

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).

https://riptutorial.com/ 54
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 declaring arrays using the new Type[length] constructor, each element will be
initialized with the following default values:

• 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.

Creating and initializing primitive type arrays


int[] array1 = new int[] { 1, 2, 3 }; // Create an array with new operator and
// array initializer.
int[] array2 = { 1, 2, 3 }; // Shortcut syntax with array initializer.
int[] array3 = new int[3]; // Equivalent to { 0, 0, 0 }
int[] array4 = null; // The array itself is an object, so it
// can be set as null.

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:

int array5[]; /*
equivalent to */ int[] array5;
int a, b[], c[][]; /*
equivalent to */ int a; int[] b; int[][] c;
int[] a, b[]; /*
equivalent to */ int[] a; int[][] b;
int a, []b, c[][]; /*
Compilation Error, because [] is not part of the type at beginning
of the declaration, rather it is before 'b'. */
// The same rules apply when declaring a method that returns an array:
int foo()[] { ... } /* equivalent to */ int[] foo() { ... }

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.

In Java, it is possible to have arrays of size 0:

int[] array = new int[0]; // Compiles and runs fine.

https://riptutorial.com/ 55
int[] array2 = {}; // Equivalent syntax.

However, since it's an empty array, no elements can be read from it or assigned to it:

array[0] = 1; // Throws java.lang.ArrayIndexOutOfBoundsException.


int i = array2[0]; // Also throws ArrayIndexOutOfBoundsException.

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.

The length of an array must be a non-negative integer:

int[] array = new int[-1]; // Throws java.lang.NegativeArraySizeException

The array size can be determined using a public final field called length:

System.out.println(array.length); // Prints 0 in this case.

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.

Creating and initializing multi-dimensional


arrays
The simplest way to create a multi-dimensional array is as follows:

int[][] a = new int[2][3];

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.

You can create and initialize at the same time:

int[][] a = { {1, 2}, {3, 4}, {5, 6} };

Unlike C, where only rectangular multi-dimensional arrays are supported, inner arrays do not need
to be of the same length, or even defined:

int[][] a = { {1}, {2, 3}, null };

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

https://riptutorial.com/ 56
((array[i])[j])[k]. Unlike C#, the syntax array[i,j] is not supported in Java.

Multidimensional array representation in Java

Source - Live on Ideone

Creating and initializing reference type arrays


String[] array6 = new String[] { "Laurel", "Hardy" }; // Create an array with new
// operator and array initializer.
String[] array7 = { "Laurel", "Hardy" }; // Shortcut syntax with array
// initializer.
String[] array8 = new String[3]; // { null, null, null }
String[] array9 = null; // null

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:

Object[] array10 = { new Object(), new Object() };

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:

Object[] array11 = new String[] { "foo", "bar", "baz" };


array11[1] = "qux"; // fine
array11[1] = new StringBuilder(); // throws ArrayStoreException

The shortcut syntax cannot be used for this because the shortcut syntax would have an implicit

https://riptutorial.com/ 57
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.

Creating and initializing generic type arrays


In generic classes, arrays of generic types cannot be initialized like this due to type erasure:

public class MyGenericClass<T> {


private T[] a;

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)

1. By creating an Object array, and casting it to the generic type:

a = (T[]) new Object[5];

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.

2. By using Array.newInstance with a class parameter:

public MyGenericClass(Class<T> clazz) {


a = (T[]) Array.newInstance(clazz, 5);
}

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.

Filling an array after initialization


Java SE 1.2

Arrays.fill() can be used to fill an array with the same value after initialization:

https://riptutorial.com/ 58
Arrays.fill(array8, "abc"); // { "abc", "abc", "abc" }

Live on Ideone

fill() can also assign a value to each element of the specified range of the array:

Arrays.fill(array8, 1, 2, "aaa"); // Placing "aaa" from index 1 to 2.

Live on Ideone

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:

int[] array = new int[5];


Arrays.setAll(array, i -> i); // The array becomes { 0, 1, 2, 3, 4 }.

Live on Ideone

Separate declaration and initialization of


arrays
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:

int[] array9; // Array declaration - uninitialized


array9 = new int[3]; // Initialize array - { 0, 0, 0 }
array9[0] = 10; // Set index 0 value - { 10, 0, 0 }
array9[1] = 20; // Set index 1 value - { 10, 20, 0 }
array9[2] = 30; // Set index 2 value - { 10, 20, 30 }

Arrays may not be re-initialized with array


initializer shortcut syntax
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.

https://riptutorial.com/ 59
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:

// First initialization of array


int[] array = new int[] { 1, 2, 3 };

// Prints "1 2 3 ".


for (int i : array) {
System.out.print(i + " ");
}

// Re-initializes array to a new int[] array.


array = new int[] { 4, 5, 6 };

// Prints "4 5 6 ".


for (int i : array) {
System.out.print(i + " ");
}

array = { 1, 2, 3, 4 }; // Compile-time error! Can't re-initialize an array via shortcut


// syntax with array initializer.

Live on Ideone

Creating an Array from a Collection

Two methods in java.util.Collection create an array from a collection:

• Object[] toArray()

• <T> T[] toArray(T[] a)

Object[] toArray() can be used as follows:

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();

<T> T[] toArray(T[] a) can be used as follows:

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

https://riptutorial.com/ 60
// be created with the same type.)
String[] stringArray = set.toArray(new String[0]);

// If you supply an array of the same size as collection or bigger, it


// will be populated with collection values and returned (new array
// won't be allocated)
String[] stringArray2 = set.toArray(new String[set.size()]);

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):

• uses vectorized arraycopy, which is much faster than the type-checked


Object[] toArray()
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.

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.

String[] strings = list.stream().toArray(String[]::new);

Examples taken from two answers (1, 2) to Converting 'ArrayList to 'String[]' in Java on Stack
Overflow.

Arrays to a String

Java SE 5

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:

int[] arr = {1, 2, 3, 4, 5};


System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4, 5]

int[][] arr = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
System.out.println(Arrays.deepToString(arr)); // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

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:

public class Cat { /* implicitly extends Object */

https://riptutorial.com/ 61
@Override
public String toString() {
return "CAT!";
}
}

Cat[] arr = { new Cat(), new Cat() };


System.out.println(Arrays.toString(arr)); // [CAT!, CAT!]

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:

public class Dog {


/* implicitly extends Object */
}

Dog[] arr = { new Dog() };


System.out.println(Arrays.toString(arr)); // [Dog@17ed40e0]

Creating a List from an Array

The Arrays.asList() method can be used to return a fixed-size List containing the elements of the
given array. The resulting List will be of the same parameter type as the base type of the array.

String[] stringArray = {"foo", "bar", "baz"};


List<String> stringList = Arrays.asList(stringArray);

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:

Java SE 5

String[] stringArray = {"foo", "bar", "baz"};


List<String> stringList = new ArrayList<String>(Arrays.asList(stringArray));

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()

String[] stringArray = {"foo", "bar", "baz"};


List<String> stringList = new ArrayList<>(Arrays.asList(stringArray));

https://riptutorial.com/ 62
// Using ArrayList.addAll()

String[] stringArray = {"foo", "bar", "baz"};


ArrayList<String> list = new ArrayList<>();
list.addAll(Arrays.asList(stringArray));

// Using Collections.addAll()

String[] stringArray = {"foo", "bar", "baz"};


ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, stringArray);

A point worth noting about the Diamond is that it cannot be used with Anonymous Classes.

Java SE 8

// Using Streams

int[] ints = {1, 2, 3};


List<Integer> list = Arrays.stream(ints).boxed().collect(Collectors.toList());

String[] stringArray = {"foo", "bar", "baz"};


List<Object> list = Arrays.stream(stringArray).collect(Collectors.toList());

Important notes related to using Arrays.asList() method


• 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:

stringList.add("something"); // throws java.lang.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:

List<String> modifiableList = new ArrayList<>(Arrays.asList("foo", "bar"));

• Calling <T> on a primitive array, such as an int[], will produce a


List<T> asList(T... 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[]
).

Therefore, this will print false:

https://riptutorial.com/ 63
int[] arr = {1, 2, 3}; // primitive array of int
System.out.println(Arrays.asList(arr).contains(1));

View Demo

On the other hand, this will print true:

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

Multidimensional and Jagged Arrays

It is possible to define an array with more than one dimension. Instead of being accessed by
providing a single index, a multidimensional array is accessed by specifying an index for each
dimension.

The declaration of multidimensional array can be done by adding [] for each dimension to a
regular array decleration. For instance, to make a 2-dimensional int array, add another set of
brackets to the declaration, such as int[][]. This continues for 3-dimensional arrays (int[][][])
and so forth.

To define a 2-dimensional array with three rows and three columns:

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.

int[][] nonRect = new int[4][];

It is important to note that although it is possible to define any dimension of jagged array, it's

https://riptutorial.com/ 64
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];

How Multidimensional Arrays are represented


in Java

Image source: http://math.hws.edu/eck/cs124/javanotes3/c8/s5.html

Jagged array literal intialization

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,

https://riptutorial.com/ 65
{},
{1},
{1,2}
};

For multidimensional array it is possible to extract arrays of lower-level dimension by their indices:

int[][][] arr = new int[3][3][3];


int[][] arr1 = arr[0]; // get first 3x3-dimensional array from arr
int[] arr2 = arr1[0]; // get first 3-dimensional array from arr1
int[] arr3 = arr[0]; // error: cannot convert from int[][] to int[]

ArrayIndexOutOfBoundsException

The ArrayIndexOutOfBoundsException is thrown when a non-existing index of an array is being


accessed.

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.

The following code is a simple example where an ArrayIndexOutOfBoundsException is thrown.

String[] people = new String[] { "Carol", "Andy" };

// An array will be created:


// people[0]: "Carol"
// people[1]: "Andy"

// Notice: no item on index 2. Trying to access it triggers the exception:


System.out.println(people[2]); // throws an ArrayIndexOutOfBoundsException.

Output:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2


at your.package.path.method(YourClass.java:15)

Note that the illegal index that is being accessed is also included in the exception (2 in the
example); this information could be useful to find the cause of the exception.

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]);
}

https://riptutorial.com/ 66
Getting the Length of an Array

Arrays are objects which provide space to store up to its size of elements of specified type. An
array's size can not be modified after the array is created.

int[] arr1 = new int[0];


int[] arr2 = new int[2];
int[] arr3 = new int[]{1, 2, 3, 4};
int[] arr4 = {1, 2, 3, 4, 5, 6, 7};

int len1 = arr1.length; // 0


int len2 = arr2.length; // 2
int len3 = arr3.length; // 4
int len4 = arr4.length; // 7

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.

public static void main(String[] args) {


Integer arr[] = new Integer[] {1,2,3,null,5,null,7,null,null,null,11,null,13};

int arrayLength = arr.length;


int nonEmptyElementsCount = 0;

for (int i=0; i<arrayLength; i++) {


Integer arrElt = arr[i];
if (arrElt != null) {
nonEmptyElementsCount++;
}
}

System.out.println("Array 'arr' has a length of "+arrayLength+"\n"


+ "and it contains "+nonEmptyElementsCount+" non-empty values");
}

Result:

Array 'arr' has a length of 13


and it contains 7 non-empty values

Comparing arrays for equality

Array types inherit their equals() (and hashCode()) implementations from java.lang.Object, so
equals() will only return true when comparing against the exact same array object. To compare
arrays for equality based on their values, use java.util.Arrays.equals, which is overloaded for all
array types.

int[] a = new int[]{1, 2, 3};


int[] b = new int[]{1, 2, 3};
System.out.println(a.equals(b)); //prints "false" because a and b refer to different objects
System.out.println(Arrays.equals(a, b)); //prints "true" because the elements of a and b have

https://riptutorial.com/ 67
the same values

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 };

Object[] aObject = { a }; // aObject contains one element


Object[] bObject = { b }; // bObject contains one element

System.out.println(Arrays.equals(aObject, bObject)); // false


System.out.println(Arrays.deepEquals(aObject, bObject));// true

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.

Arrays to Stream

Java SE 8

Converting an array of objects to Stream:

String[] arr = new String[] {"str1", "str2", "str3"};


Stream<String> stream = Arrays.stream(arr);

Converting an array of primitives to Stream using Arrays.stream() will transform the array to a
primitive specialization of Stream:

int[] intArr = {1, 2, 3};


IntStream intStream = Arrays.stream(intArr);

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:

int[] values = {1, 2, 3, 4};


IntStream intStream = Arrays.stream(values, 2, 4);

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:

Stream<Integer> intStream = Stream.of(1, 2, 3);


Stream<String> stringStream = Stream.of("1", "2", "3");
Stream<Double> doubleStream = Stream.of(new Double[]{1.0, 2.0});

Iterating over arrays

https://riptutorial.com/ 68
You can iterate over arrays either by using enhanced for loop (aka foreach) or by using array
indices:

int[] array = new int[10];

// using indices: read and write


for (int i = 0; i < array.length; i++) {
array[i] = i;
}

Java SE 5

// extended for: read only


for (int e : array) {
System.out.println(e);
}

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 boxed arrays use Arrays.asList:

Integer[] boxed = {1, 2, 3};


Iterable<Integer> boxedIt = Arrays.asList(boxed); // list-backed iterable
Iterator<Integer> fromBoxed1 = boxedIt.iterator();

For primitive arrays (using java 8) use streams (specifically in this example - Arrays.stream ->
IntStream):

int[] primitives = {1, 2, 3};


IntStream primitiveStream = Arrays.stream(primitives); // list-backed iterable
PrimitiveIterator.OfInt fromPrimitive1 = primitiveStream.iterator();

If you can't use streams (no java 8), you can choose to use google's guava library:

Iterable<Integer> fromPrimitive2 = Ints.asList(primitives);

In two-dimensional arrays or more, both techniques can be used in a slightly more complex
fashion.

Example:

int[][] array = new int[10][10];

for (int indexOuter = 0; indexOuter < array.length; indexOuter++) {


for (int indexInner = 0; indexInner < array[indexOuter].length; indexInner++) {
array[indexOuter][indexInner] = indexOuter + indexInner;
}
}

Java SE 5

https://riptutorial.com/ 69
for (int[] numbers : array) {
for (int value : numbers) {
System.out.println(value);
}
}

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:

int[] numbers = {1, 2, 3, 4};

public void incrementNumbers() {


// DO THIS :
for (int i = 0; i < numbers.length; i++) {
numbers[i] += 1; //or this: numbers[i] = numbers[i] + 1; or numbers[i]++;
}

// 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:

public void fillArrayWithDoubleIndex(int[] array) {


// DO THIS :
for (int i = 0; i < array.length; i++) {
array[i] = i * 2;
}

// DON'T DO THIS :
int doubleLength = array.length * 2;
for (int i = 0; i < doubleLength; i += 2) {
array[i / 2] = i;
}
}

Accessing Arrays in reverse order

int[] array = {0, 1, 1, 2, 3, 5, 8, 13};


for (int i = array.length - 1; i >= 0; i--) {
System.out.println(array[i]);

https://riptutorial.com/ 70
}

Using temporary Arrays to reduce code repetition

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.

// we want to print out all of these


String name = "Margaret";
int eyeCount = 16;
double height = 50.2;
int legs = 9;
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);

// temporary array approach:


for(Object attribute : new Object[]{name, eyeCount, height, legs, arms})
System.out.println(attribute);

// using only numbers


for(double number : new double[]{eyeCount, legs, arms, height})
System.out.println(Math.sqrt(number));

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.

Copying arrays

Java provides several ways to copy an array.

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];
}

Note that using this option with an Object array instead of primitive array will fill the copy with
reference to the original content instead of copy of it.

https://riptutorial.com/ 71
Object.clone()
Since arrays are Objects in Java, you can use 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:

int[] a = {4, 1, 3, 2};


int[] b = Arrays.copyOf(a, a.length); // [4, 1, 3, 2]

Note that Arrays.copyOf also provides an overload which allows you to change the type of the
array:

Double[] doubles = { 1.0, 2.0, 3.0 };


Number[] numbers = Arrays.copyOf(doubles, doubles.length, Number[].class);

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.

Below an example of use

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:

https://riptutorial.com/ 72
int[] a = { 4, 1, 3, 2 };
int[] b = Arrays.copyOfRange(a, 0, a.length); // [4, 1, 3, 2]

Casting Arrays

Arrays are objects, but their type is defined by the type of the contained objects. Therefore, one
cannot just cast A[] to T[], but each A member of the specific A[] must be cast to a T object.
Generic example:

public static <T, A> T[] castArray(T[] target, A[] array) {


for (int i = 0; i < array.length; i++) {
target[i] = (T) array[i];
}
return target;
}

Thus, given an A[] array:

T[] target = new T[array.Length];


target = castArray(target, array);

Java SE provides the method Arrays.copyOf(original, newLength, newType) for this purpose:

Double[] doubles = { 1.0, 2.0, 3.0 };


Number[] numbers = Arrays.copyOf(doubles, doubles.length, Number[].class);

Remove an element from an array

Java doesn't provide a direct method in java.util.Arrays to remove an element from an array. To
perform it, you can either copy the original array to a new one without the element to remove or
convert your array to another structure allowing the removal.

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:

String[] array = new String[]{"foo", "bar", "baz"};

List<String> list = new ArrayList<>(Arrays.asList(array));


list.remove("foo");

// 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()]);

System.out.println(Arrays.toString(array)); //[bar, baz]

https://riptutorial.com/ 73
Using System.arraycopy
can be used to make a copy of the original array and remove the element you
System.arraycopy()
want. Below an example:

int[] array = new int[] { 1, 2, 3, 4 }; // Original array.


int[] result = new int[array.length - 1]; // Array which will contain the result.
int index = 1; // Remove the value "2".

// Copy the elements at the left of the index.


System.arraycopy(array, 0, result, 0, index);
// Copy the elements at the right of the index.
System.arraycopy(array, index + 1, result, index, array.length - index - 1);

System.out.println(Arrays.toString(result)); //[1, 3, 4]

Using Apache Commons Lang


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:

int[] array = new int[]{1,2,3,4};


array = ArrayUtils.removeElement(array, 2); //remove first occurrence of 2
System.out.println(Arrays.toString(array)); //[1, 3, 4]

Array Covariance

Object arrays are covariant, which means that just as Integer is a subclass of Number, Integer[] is a
subclass of Number[]. This may seem intuitive, but can result in surprising behavior:

Integer[] integerArray = {1, 2, 3};


Number[] numberArray = integerArray; // valid
Number firstElement = numberArray[0]; // valid
numberArray[0] = 4L; // throws ArrayStoreException at runtime

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:

List<Integer> integerList = Arrays.asList(1, 2, 3);


//List<Number> numberList = integerList; // compile error
List<? extends Number> numberList = integerList;
Number firstElement = numberList.get(0);
//numberList.set(0, 4L); // compile error

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:

https://riptutorial.com/ 74
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[] array12 = new I[3]; // { null, null, null }

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.

Object[] array15 = { new A(), 64, "My String" }; // Shortcut syntax


// with array initializer.

How do you change the size of an array?

The simple answer is that you cannot do this. Once an array has been created, its size cannot be
changed. Instead, an array can only be "resized" by creating a new array with the appropriate size
and copying the elements from the existing array to the new one.

String[] listOfCities = new String[3]; // array created with size 3.


listOfCities[0] = "New York";
listOfCities[1] = "London";
listOfCities[2] = "Berlin";

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:

1. create a new array with size 4,


2. copy the existing 3 elements of the old array to the new array at offsets 0, 1 and 2, and
3. add the new element to the new array at offset 3.

There are various ways to do the above. Prior to Java 6, the most concise way was:

String[] newArray = new String[listOfCities.length + 1];


System.arraycopy(listOfCities, 0, newArray, 0, listOfCities.length);
newArray[listOfCities.length] = "Sydney";

From Java 6 onwards, the Arrays.copyOf and Arrays.copyOfRange methods can do this more simply:

String[] newArray = Arrays.copyOf(listOfCities, listOfCities.length + 1);


newArray[listOfCities.length] = "Sydney";

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.

https://riptutorial.com/ 75
• Copying arrays

A better alternatives to array resizing


There two major drawbacks with resizing an array as described above:

• 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.)

Finding an element in an array

There are many ways find the location of a value in an array. The following example snippets all
assume that the array is one of the following:

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 Arrays.binarySearch (for sorted arrays only)

int index = Arrays.binarySearch(strings, "A");


int index2 = Arrays.binarySearch(ints, 1);

Using a Arrays.asList (for non-primitive arrays only)

int index = Arrays.asList(strings).indexOf("A");

https://riptutorial.com/ 76
int index2 = Arrays.asList(ints).indexOf(1); // compilation error

Using a Stream
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

Linear search using a loop

int index = -1;


for (int i = 0; i < array.length; i++) {
if ("A".equals(array[i])) {
index = i;
break;
}
}
// Similar for an array of primitives

Linear search using 3rd-party libraries such as


org.apache.commons

int index = org.apache.commons.lang3.ArrayUtils.contains(strings, "A");


int index2 = org.apache.commons.lang3.ArrayUtils.contains(ints, 1);

Note: Using a direct linear search is more efficient than wrapping in a list.

Testing if an array contains an element


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.

Alternatively, there are also some more concise variations:

boolean isPresent = Arrays.asList(strings).contains("A");

Java SE 8

boolean isPresent = Stream<String>.of(strings).anyMatch(x -> "A".equals(x));

boolean isPresent = false;


for (String s : strings) {
if ("A".equals(s)) {

https://riptutorial.com/ 77
isPresent = true;
break;
}
}

boolean isPresent = org.apache.commons.lang3.ArrayUtils.contains(ints, 4);

Sorting arrays

Sorting arrays can be easily done with the Arrays api.

import java.util.Arrays;

// creating an array with integers


int[] array = {7, 4, 2, 1, 19};
// this is the sorting part just one function ready to be used
Arrays.sort(array);
// prints [1, 2, 4, 7, 19]
System.out.println(Arrays.toString(array));

Sorting String 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

String[] names = {"John", "Steve", "Shane", "Adam", "Ben"};


System.out.println("String array before sorting : " + Arrays.toString(names));
Arrays.sort(names);
System.out.println("String array after sorting in ascending order : " +
Arrays.toString(names));

Output:

String array before sorting : [John, Steve, Shane, Adam, Ben]


String array after sorting in ascending order : [Adam, Ben, John, Shane, Steve]

Decreasing Order

Arrays.sort(names, 0, names.length, Collections.reverseOrder());


System.out.println("String array after sorting in descending order : " +
Arrays.toString(names));

Output:

String array after sorting in descending order : [Steve, Shane, John, Ben, Adam]

Sorting an Object array

https://riptutorial.com/ 78
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);

System.out.println("Object array before sorting : " + Arrays.toString(courses));

Arrays.sort(courses);
System.out.println("Object array after sorting in natural order : " +
Arrays.toString(courses));

Arrays.sort(courses, new Course.PriceComparator());


System.out.println("Object array after sorting by price : " + Arrays.toString(courses));

Arrays.sort(courses, new Course.NameComparator());


System.out.println("Object array after sorting by name : " + 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 ]

Converting arrays between primitives and boxed types

Sometimes conversion of primitive types to boxed types is necessary.

To convert the array, it's possible to use streams (in Java 8 and above):

Java SE 8

int[] primitiveArray = {1, 2, 3, 4};


Integer[] boxedArray =
Arrays.stream(primitiveArray).boxed().toArray(Integer[]::new);

With lower versions it can be by iterating the primitive array and explicitly copying it to the boxed
array:

https://riptutorial.com/ 79
Java SE 8

int[] primitiveArray = {1, 2, 3, 4};


Integer[] boxedArray = new Integer[primitiveArray.length];
for (int i = 0; i < primitiveArray.length; ++i) {
boxedArray[i] = primitiveArray[i]; // Each element is autoboxed here
}

Similarly, a boxed array can be converted to an array of its primitive counterpart:

Java SE 8

Integer[] boxedArray = {1, 2, 3, 4};


int[] primitiveArray =
Arrays.stream(boxedArray).mapToInt(Integer::intValue).toArray();

Java SE 8

Integer[] boxedArray = {1, 2, 3, 4};


int[] primitiveArray = new int[boxedArray.length];
for (int i = 0; i < boxedArray.length; ++i) {
primitiveArray[i] = boxedArray[i]; // Each element is outboxed here
}

Read Arrays online: https://riptutorial.com/java/topic/99/arrays

https://riptutorial.com/ 80
Chapter 9: Asserting
Syntax
• assert expression1;
• assert expression1 : expression2;

Parameters

Parameter Details

The assertion statement throws an AssertionError if this expression evaluates


expression1
to false.

Optional. When used, AssertionErrors thrown by the assert statement have this
expression2
message.

Remarks
By default, assertions are disabled at runtime.

To enable assertions, you must run java with -ea flag.

java -ea com.example.AssertionExample

Assertions are statements that will throw an error if their expression evaluates to false. Assertions
should only be used to test code; they should never be used in production.

Examples
Checking arithmetic with assert

a = 1 - Math.abs(1 - a % 2);

// This will throw an error if my arithmetic above is wrong.


assert a >= 0 && a <= 1 : "Calculated value of " + a + " is outside of expected bounds";

return a;

Read Asserting online: https://riptutorial.com/java/topic/407/asserting

https://riptutorial.com/ 81
Chapter 10: Atomic Types
Introduction
Java Atomic Types are simple mutable types that provide basic operations that are thread-safe
and atomic without resorting to locking. They are intended for use in cases where locking would be
a concurrency bottleneck, or where there is risk of deadlock or livelock.

Parameters

Parameter Description

set Volatile set of the field

get Volatile read of the field

lazySet This is a store ordered operation of the field

compareAndSet If the value is the expeed value then sent it to the new value

getAndSet get the current value and update

Remarks
Many on essentially combinations of volatile reads or writes and CAS operations. Best way to
understand this is to look at the source code directly. E.g. AtomicInteger, Unsafe.getAndSet

Examples
Creating Atomic Types

For simple multi-threaded code, using synchronization is acceptable. However, using


synchronization does have a liveness impact, and as a codebase becomes more complex, the
likelihood goes up that you will end up with Deadlock, Starvation, or Livelock.

In cases of more complex concurrency, using Atomic Variables is often a better alternative, as it
allows an individual variable to be accessed in a thread-safe manner without the overhead of
using synchronized methods or code blocks.

Creating an AtomicInteger type:

AtomicInteger aInt = new AtomicInteger() // Create with default value 0

AtomicInteger aInt = new AtomicInteger(1) // Create with initial value 1

https://riptutorial.com/ 82
Similarly for other instance types.

AtomicIntegerArray aIntArray = new AtomicIntegerArray(10) // Create array of specific length


AtomicIntegerArray aIntArray = new AtomicIntegerArray(new int[] {1, 2, 3}) // Initialize array
with another array

Similarly for other atomic types.

There is a notable exception that there is no float and double types. These can be simulated
through the use of Float.floatToIntBits(float) and Float.intBitsToFloat(int) for float as well as
Double.doubleToLongBits(double) and Double.longBitsToDouble(long) for doubles.

If you are willing to use sun.misc.Unsafe you can use any primitive variable as atomic by using the
atomic operation in sun.misc.Unsafe. All primitive types should be converted or encoded in int or
longs to so use it in this way. For more on this see: sun.misc.Unsafe.

Motivation for Atomic Types

The simple way to implement multi-threaded applications is to use Java's built-in synchronization
and locking primitives; e.g. the synchronized keyword. The following example shows how we might
use synchronized to accumulate counts.

public class Counters {


private final int[] counters;

public Counters(int nosCounters) {


counters = new int[nosCounters];
}

/**
* Increments the integer at the given index
*/
public synchronized void count(int number) {
if (number >= 0 && number < counters.length) {
counters[number]++;
}
}

/**
* Obtains the current count of the number at the given index,
* or if there is no number at that index, returns 0.
*/
public synchronized int getCount(int number) {
return (number >= 0 && number < counters.length) ? counters[number] : 0;
}
}

This implementation will work correctly. However, if you have a large number of threads making
lots of simultaneous calls on the same Counters object, the synchronization is liable to be a
bottleneck. Specifically:

1. Each synchronized method call will start with the current thread acquiring the lock for the
Counters instance.

https://riptutorial.com/ 83
2. The thread will hold the lock while it checks number value and updates the counter.
3. Finally, the it will release the lock, allowing other threads access.

If one thread attempts to acquire the lock while another one holds it, the attempting thread will be
blocked (stopped) at step 1 until the lock is released. If multiple threads are waiting, one of them
will get it, and the others will continue to be blocked.

This can lead to a couple of problems:

• If there is a lot of contention for the lock (i.e. lots of thread try to acquire it), then some
threads can be blocked for a long time.

• When a thread is blocked waiting for the lock, the operating system will typically try switch
execution to a different thread. This context switching incurs a relatively large performance
impact on the processor.

• When there are multiple threads blocked on the same lock, there are no guarantees that any
one of them will be treated "fairly" (i.e. each thread is guaranteed to be scheduled to run).
This can lead to thread starvation.

How does one implement Atomic Types?


Let us start by rewriting the example above using AtomicInteger counters:

public class Counters {


private final AtomicInteger[] counters;

public Counters(int nosCounters) {


counters = new AtomicInteger[nosCounters];
for (int i = 0; i < nosCounters; i++) {
counters[i] = new AtomicInteger();
}
}

/**
* Increments the integer at the given index
*/
public void count(int number) {
if (number >= 0 && number < counters.length) {
counters[number].incrementAndGet();
}
}

/**
* Obtains the current count of the object at the given index,
* or if there is no number at that index, returns 0.
*/
public int getCount(int number) {
return (number >= 0 && number < counters.length) ?
counters[number].get() : 0;
}
}

We have replaced the int[] with an AtomicInteger[], and initialized it with an instance in each

https://riptutorial.com/ 84
element. We have also added calls to incrementAndGet() and get() in place of operations on int
values.

But the most important thing is that we can remove the synchronized keyword because locking is
no longer required. This works because the incrementAndGet() and get() operations are atomic and
thread-safe. In this context, it means that:

• Each counter in the array will only be observable in the either the "before" state for an
operation (like an "increment") or in the "after" state.

• Assuming that the operation occurs at time T, no thread will be able to see the "before" state
after time T.

Furthermore, while two threads might actually attempt to update the same AtomicInteger instance
at the same time, the implementations of the operations ensure that only one increment happens
at a time on the given instance. This is done without locking, often resulting in better performance.

How do Atomic Types work?


Atomic types typically rely on specialized hardware instructions in the instruction set of the target
machine. For example, Intel-based instruction sets provide a CAS (Compare and Swap) instruction
that will perform a specific sequence of memory operations atomically.

These low-level instructions are are used to implement higher-level operations in the APIs of the
respective AtomicXxx classes. For example, (again, in C-like pseudocode):

private volatile num;

int increment() {
while (TRUE) {
int old = num;
int new = old + 1;
if (old == compare_and_swap(&num, old, new)) {
return new;
}
}
}

If there is no contention on the AtomicXxxx, the if test will succeed and the loop will end
immediately. If there is contention, then the if will fail for all but one of the threads, and they will
"spin" in the loop for a small number of cycles of the loop. In practice, the spinning is orders of
magnitude faster (except at unrealistically high levels of contention, where synchronized performs
better than atomic classes because when the CAS operation fails, then the retry will only add more
contention) than suspending the thread and switching to another one.

Incidentally, CAS instructions are typically used by the JVM to implement uncontended locking. If
the JVM can see that a lock is not currently locked, it will attempt to use a CAS to acquire the lock.
If the CAS succeeds, then there is no need to do the expensive thread scheduling, context
switching and so on. For more information on the techniques used, see Biased Locking in HotSpot
.

https://riptutorial.com/ 85
Read Atomic Types online: https://riptutorial.com/java/topic/5963/atomic-types

https://riptutorial.com/ 86
Chapter 11: Audio
Remarks
Instead of using the javax.sound.sampled Clip, you can also use the AudioClip which is from the
applet API. It is however recommended to use Clip since AudioClip is just older and presents
limited functionalities.

Examples
Play an Audio file Looped

Needed imports:

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;

This code will create a clip and play it continuously once started:

Clip clip = AudioSystem.getClip();


clip.open(AudioSystem.getAudioInputStream(new URL(filename)));
clip.start();
clip.loop(Clip.LOOP_CONTINUOUSLY);

Get an Array with all supported file types:

AudioFileFormat.Type [] audioFileTypes = AudioSystem.getAudioFileTypes();

Play a MIDI file

MIDI files can be played by using several classes from the javax.sound.midi package. A Sequencer
performs playback of the MIDI file, and many of its methods can be used to set playback controls
such as loop count, tempo, track muting, and others.

General playback of MIDI data can be done in this way:

import java.io.File;
import java.io.IOException;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;

public class MidiPlayback {


public static void main(String[] args) {
try {
Sequencer sequencer = MidiSystem.getSequencer(); // Get the default Sequencer

https://riptutorial.com/ 87
if (sequencer==null) {
System.err.println("Sequencer device not supported");
return;
}
sequencer.open(); // Open device
// Create sequence, the File must contain MIDI file data.
Sequence sequence = MidiSystem.getSequence(new File(args[0]));
sequencer.setSequence(sequence); // load it into sequencer
sequencer.start(); // start the playback
} catch (MidiUnavailableException | InvalidMidiDataException | IOException ex) {
ex.printStackTrace();
}
}
}

To stop the playback use:

sequencer.stop(); // Stop the playback

A sequencer can be set to mute one or more of the sequence's tracks during playback so none of
the instruments in those specified play. The following example sets the first track in the sequence
to be muted:

import javax.sound.midi.Track;
// ...

Track[] track = sequence.getTracks();


sequencer.setTrackMute(track[0]);

A sequencer can play a sequence repeatedly if the loop count is given. The following sets the
sequencer to play a sequence four times and indefinitely:

sequencer.setLoopCount(3);
sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);

The sequencer does not always have to play the sequence from the beginning, nor does it have to
play the sequence until the end. It can start and end at any point by specifying the tick in the
sequence to start and end at. It is also possible to specify manually which tick in the sequence the
sequencer should play from:

sequencer.setLoopStartPoint(512);
sequencer.setLoopEndPoint(32768);
sequencer.setTickPosition(8192);

Sequencers can also play a MIDI file at a certain tempo, which can be controlled by specifying the
tempo in beats per minute (BPM) or microseconds per quarter note (MPQ). The factor at which the
sequence is played can be adjusted as well.

sequencer.setTempoInBPM(1250f);
sequencer.setTempoInMPQ(4750f);
sequencer.setTempoFactor(1.5f);

https://riptutorial.com/ 88
When you finished using the Sequencer, remeber to close it

sequencer.close();

Bare metal sound

You can also go almost bare-metal when producing sound with java. This code will write raw
binary data into the OS audio buffer to generate sound. It's extremely important to understand the
limitations and necessary calculations to generating sound like this. Since playback is basically
instantaneous, calculations need to be performed at almost real-time.

As such this method is unusable for more complicated sound-sampling. For such purposes using
specialized tools is the better approach.

The following method generates and directly outputs a rectangle-wave of a given frequency in a
given volume for a given duration.

public void rectangleWave(byte volume, int hertz, int msecs) {


final SourceDataLine dataLine;
// 24 kHz x 8bit, single-channel, signed little endian AudioFormat
AudioFormat af = new AudioFormat(24_000, 8, 1, true, false);
try {
dataLine = AudioSystem.getSourceDataLine(af);
dataLine.open(af, 10_000); // audio buffer size: 10k samples
} catch (LineUnavailableException e) {
throw new RuntimeException(e);
}

int waveHalf = 24_000 / hertz; // samples for half a period


byte[] buffer = new byte[waveHalf * 20];
int samples = msecs * (24_000 / 1000); // 24k (samples / sec) / 1000 (ms/sec) * time(ms)

dataLine.start(); // starts playback


int sign = 1;

for (int i = 0; i < samples; i += buffer.length) {


for (int j = 0; j < 20; j++) { // generate 10 waves into buffer
sign *= -1;
// fill from the jth wave-half to the j+1th wave-half with volume
Arrays.fill(buffer, waveHalf * j, waveHalf * (j+1), (byte) (volume * sign));
}
dataLine.write(buffer, 0, buffer.length); //
}
dataLine.drain(); // forces buffer drain to hardware
dataLine.stop(); // ends playback
}

For a more differentiated way to generate different soundwaves sinus calculations and possibly
larger sample sizes are necessary. This results in significantly more complex code and is
accordingly omitted here.

Basic audio output

The Hello Audio! of Java that plays a sound file from local or internet storage looks as follows. It

https://riptutorial.com/ 89
works for uncompressed .wav files and should not be used for playing mp3 or compressed files.

import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;

public class SoundClipTest {

// Constructor
public SoundClipTest() {
try {
// Open an audio input stream.
File soundFile = new File("/usr/share/sounds/alsa/Front_Center.wav"); //you could
also get the sound file with an URL
AudioInputStream audioIn = AudioSystem.getAudioInputStream(soundFile);
AudioFormat format = audioIn.getFormat();
// Get a sound clip resource.
DataLine.Info info = new DataLine.Info(Clip.class, format);
Clip clip = (Clip)AudioSystem.getLine(info);
// Open audio clip and load samples from the audio input stream.
clip.open(audioIn);
clip.start();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {


new SoundClipTest();
}
}

Read Audio online: https://riptutorial.com/java/topic/160/audio

https://riptutorial.com/ 90
Chapter 12: Autoboxing
Introduction
Autoboxing is the automatic conversion that Java compiler makes between primitive types and
their corresponding object wrapper classes. Example, converting int -> Integer, double -> Double...
If the conversion goes the other way, this is called unboxing. Typically, this is used in Collections
that cannot hold other than Objects, where boxing primitive types is needed before setting them in
the collection.

Remarks
Autoboxing can have performance issues when used frequently in your code.

• http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html
• Integer auto-unboxing and auto-boxing gives performance issues?

Examples
Using int and Integer interchangeably

As you use generic types with utility classes, you may often find that number types aren't very
helpful when specified as the object types, as they aren't equal to their primitive counterparts.

List<Integer> ints = new ArrayList<Integer>();

Java SE 7

List<Integer> ints = new ArrayList<>();

Fortunately, expressions that evaluate to int can be used in place of an Integer when it is needed.

for (int i = 0; i < 10; i++)


ints.add(i);

The ints.add(i); statement is equivalent to:

ints.add(Integer.valueOf(i));

And retains properties from Integer#valueOf such as having the same Integer objects cached by
the JVM when it is within the number caching range.

This also applies to:

• byte and Byte

https://riptutorial.com/ 91
• short and Short
• float and Float
• double and Double
• long and Long
• char and Character
• boolean and Boolean

Care must be taken, however, in ambiguous situations. Consider the following code:

List<Integer> ints = new ArrayList<Integer>();


ints.add(1);
ints.add(2);
ints.add(3);
ints.remove(1); // ints is now [1, 3]

The java.util.List interface contains both a remove(int index) (List interface method) and a
remove(Object o) (method inherited from java.util.Collection). In this case no boxing takes place
and remove(int index) is called.

One more example of strange Java code behavior caused by autoboxing Integers with values in
range from -128 to 127:

Integer a = 127;
Integer b = 127;
Integer c = 128;
Integer d = 128;
System.out.println(a == b); // true
System.out.println(c <= d); // true
System.out.println(c >= d); // true
System.out.println(c == d); // false

This happens because >= operator implicitly calls intValue() which returns int while == compares
references, not the int values.

By default, Java caches values in range [-128, 127], so the operator == works because the
Integers in this range reference to the same objects if their values are same. Maximal value of the
cacheable range can be defined with -XX:AutoBoxCacheMax JVM option. So, if you run the program
with -XX:AutoBoxCacheMax=1000, the following code will print true:

Integer a = 1000;
Integer b = 1000;
System.out.println(a == b); // true

Using Boolean in if statement

Due to auto unboxing, one can use a Boolean in an if statement:

Boolean a = Boolean.TRUE;
if (a) { // a gets converted to boolean
System.out.println("It works!");
}

https://riptutorial.com/ 92
That works for while, do while and the condition in the for statements as well.

Note that, if the Boolean is null, a NullPointerException will be thrown in the conversion.

Auto-unboxing may lead to NullPointerException

This code compiles:

Integer arg = null;


int x = arg;

But it will crash at runtime with a java.lang.NullPointerException on the second line.

The problem is that a primitive int cannot have a null value.

This is a minimalistic example, but in practice it often manifests in more sophisticated forms. The
NullPointerException is not very intuitive and is often little help in locating such bugs.

Rely on autoboxing and auto-unboxing with care, make sure that unboxed values will not have
null values at runtime.

Memory and Computational Overhead of Autoboxing

Autoboxing can come at a substantial memory overhead. For example:

Map<Integer, Integer> square = new HashMap<Integer, Integer>();


for(int i = 256; i < 1024; i++) {
square.put(i, i * i); // Autoboxing of large integers
}

will typically consume substantial amount of memory (about 60kb for 6k of actual data).

Furthermore, boxed integers usually require additional round-trips in the memory, and thus make
CPU caches less effective. In above example, the memory accessed is spread out to five different
locations that may be in entirely different regions of the memory: 1. the HashMap object, 2. the map's
Entry[] table object, 3. the Entry object, 4. the entrys key object (boxing the primitive key), 5. the
entrys value object (boxing the primitive value).

class Example {
int primitive; // Stored directly in the class `Example`
Integer boxed; // Reference to another memory location
}

Reading boxed requires two memory accesses, accessing primitive only one.

When getting data from this map, the seemingly innocent code

int sumOfSquares = 0;
for(int i = 256; i < 1024; i++) {
sumOfSquares += square.get(i);

https://riptutorial.com/ 93
}

is equivalent to:

int sumOfSquares = 0;
for(int i = 256; i < 1024; i++) {
sumOfSquares += square.get(Integer.valueOf(i)).intValue();
}

Typically, the above code causes the creation and garbage collection of an Integer object for
every Map#get(Integer) operation. (See Note below for more details.)

To reduce this overhead, several libraries offer optimized collections for primitive types that do not
require boxing. In addition to avoiding the boxing overhead, these collection will require about 4x
less memory per entry. While Java Hotspot may be able to optimize the autoboxing by working
with objects on the stack instead of the heap, it is not possible to optimize the memory overhead
and resulting memory indirection.

Java 8 streams also have optimized interfaces for primitive data types, such as IntStream that do
not require boxing.

Note: a typical Java runtime maintains a simple cache of Integer and other primitive wrapper
object that is used by the valueOf factory methods, and by autoboxing. For Integer, the default
range of this cache is -128 to +127. Some JVMs provide a JVM command-line option for changing
the cache size / range.

Different Cases When Integer and int can be used interchangeably

Case 1: While using in the place of method arguments.

If a method requires an object of wrapper class as argument.Then interchangeably the argument


can be passed a variable of the respective primitive type and vice versa.

Example:

int i;
Integer j;
void ex_method(Integer i)//Is a valid statement
void ex_method1(int j)//Is a valid statement

Case 2: While passing return values:

When a method returns a primitive type variable then an object of corresponding wrapper class
can be passed as the return value interchangeably and vice versa.

Example:

int i;
Integer j;
int ex_method()

https://riptutorial.com/ 94
{...
return j;}//Is a valid statement
Integer ex_method1()
{...
return i;//Is a valid statement
}

Case 3: While performing operations.

Whenever performing operations on numbers the primitive type variable and object of respective
wrapper class can be used interchangeably.

int i=5;
Integer j=new Integer(7);
int k=i+j;//Is a valid statement
Integer m=i+j;//Is also a valid statement

Pitfall:Remember to initialize or assign a value to an object of the wrapper class.

While using wrapper class object and primitive variable interchangeably never forget or miss to
initialize or assign a value to the wrapper class object else it may lead to null pointer exception at
runtime.

Example:

public class Test{


Integer i;
int j;
public void met()
{j=i;//Null pointer exception
SOP(j);
SOP(i);}
public static void main(String[] args)
{Test t=new Test();
t.go();//Null pointer exception
}

In the above example, the value of the object is unassigned and uninitialized and thus at runtime
the program will run into null pointer exception.So as clear from the above example the value of
object should never be left uninitialized and unassigned.

Read Autoboxing online: https://riptutorial.com/java/topic/138/autoboxing

https://riptutorial.com/ 95
Chapter 13: Basic Control Structures
Remarks
All control structures, unless otherwise noted, make use of block statements. These are denoted
by curly braces {}.

This differs from normal statements, which do not require curly braces, but also come with a stiff
caveat in that only the line immediately following the previous statement would be considered.

Thus, it is perfectly valid to write any of these control structures without curly braces, so long as
only one statement follows the beginning, but it is strongly discouraged, as it can lead to buggy
implementations, or broken code.

Example:

// valid, but discouraged


Scanner scan = new Scanner(System.in);
int val = scan.nextInt();
if(val % 2 == 0)
System.out.println("Val was even!");

// invalid; will not compile


// note the misleading indentation here
for(int i = 0; i < 10; i++)
System.out.println(i);
System.out.println("i is currently: " + i);

Examples
If / Else If / Else Control

if (i < 2) {
System.out.println("i is less than 2");
} else if (i > 2) {
System.out.println("i is more than 2");
} else {
System.out.println("i is not less than 2, and not more than 2");
}

The if block will only run when i is 1 or less.

The else if condition is checked only if all the conditions before it (in previous else if constructs,
and the parent if constructs) have been tested to false. In this example, the else if condition will
only be checked if i is greater than or equal to 2.

If its result is true, its block is run, and any else if and else constructs after it will be skipped.

https://riptutorial.com/ 96
If none of the if and else if conditions have been tested to true, the else block at the end will be
run.

For Loops

for (int i = 0; i < 100; i++) {


System.out.println(i);
}

The three components of the for loop (separated by ;) are variable declaration/initialization (here
int i = 0), the condition (here i < 100), and the increment statement (here i++). The variable
declaration is done once as if placed just inside the { on the first run. Then the condition is
checked, if it is true the body of the loop will execute, if it is false the loop will stop. Assuming the
loop continues, the body will execute and finally when the } is reached the increment statement
will execute just before the condition is checked again.

The curly braces are optional (you can one line with a semicolon) if the loop contains just one
statement. But, it's always recommended to use braces to avoid misunderstandings and bugs.

The for loop components are optional. If your business logic contains one of these parts, you can
omit the corresponding component from your for loop.

int i = obj.getLastestValue(); // i value is fetched from a method

for (; i < 100; i++) { // here initialization is not done


System.out.println(i);
}

The for (;;) { function-body } structure is equal to a while (true) loop.

Nested For Loops

Any looping statement having another loop statement inside called nested loop. The same way for
looping having more inner loop is called 'nested for loop'.

for(;;){
//Outer Loop Statements
for(;;){
//Inner Loop Statements
}
//Outer Loop Statements
}

Nested for loop can be demonstrated to print triangle shaped numbers.

for(int i=9;i>0;i--){//Outer Loop


System.out.println();
for(int k=i;k>0;k--){//Inner Loop -1
System.out.print(" ");
}
for(int j=i;j<=9;j++){//Inner Loop -2
System.out.print(" "+j);

https://riptutorial.com/ 97
}
}

While Loops

int i = 0;
while (i < 100) { // condition gets checked BEFORE the loop body executes
System.out.println(i);
i++;
}

A while loop runs as long as the condition inside the parentheses is true. This is also called the
"pre-test loop" structure because the conditional statement must be met before the main loop body
is performed every time.

The curly braces are optional if the loop contains just one statement, but some coding style
conventions prefers having the braces regardless.

do...while Loop

The do...while loop differs from other loops in that it is guaranteed to execute at least once. It is
also called the "post-test loop" structure because the conditional statement is performed after the
main loop body.

int i = 0;
do {
i++;
System.out.println(i);
} while (i < 100); // Condition gets checked AFTER the content of the loop executes.

In this example, the loop will run until the number 100 is printed (even though the condition is i <
100 and not i <= 100), because the loop condition is evaluated after the loop executes.

With the guarantee of at least one execution, it is possible to declare variables outside of the loop
and initialize them inside.

String theWord;
Scanner scan = new Scanner(System.in);
do {
theWord = scan.nextLine();
} while (!theWord.equals("Bird"));

System.out.println(theWord);

In this context, theWord is defined outside of the loop, but since it's guaranteed to have a value
based on its natural flow, theWord will be initialized.

For Each

Java SE 5

https://riptutorial.com/ 98
With Java 5 and up, one can use for-each loops, also known as enhanced for-loops:

List strings = new ArrayList();

strings.add("This");
strings.add("is");
strings.add("a for-each loop");

for (String string : strings) {


System.out.println(string);
}

For each loops can be used to iterate over Arrays and implementations of the Iterable interface,
the later includes Collections classes, such as List or Set.

The loop variable can be of any type that is assignable from the source type.

The loop variable for a enhanced for loop for Iterable<T> or T[] can be of type S, if

• T extends S
• both T and S are primitive types and assignable without a cast
• S is a primitive type and T can be converted to a type assignable to S after unboxing
conversion.
• T is a primitive type and can be converted to S by autoboxing conversion.

Examples:

T elements = ...
for (S s : elements) {
}

T S Compiles

int[] long yes

long[] int no

Iterable<Byte> long yes

Iterable<String> CharSequence yes

Iterable<CharSequence> String no

int[] Long no

int[] Integer yes

If / Else

int i = 2;

https://riptutorial.com/ 99
if (i < 2) {
System.out.println("i is less than 2");
} else {
System.out.println("i is greater than 2");
}

An if statement executes code conditionally depending on the result of the condition in


parentheses. When condition in parentheses is true it will enter to the block of if statement which is
defined by curly braces like { and }. opening bracket till the closing bracket is the scope of the if
statement.

The else block is optional and can be omitted. It runs if the if statement is false and does not run
if the if statement is true Because in that case if statement executes.

See also: Ternary If

Switch statement

The switch statement is Java's multi-way branch statement. It is used to take the place of long if-
else if-else chains, and make them more readable. However, unlike if statements, one may not
use inequalities; each value must be concretely defined.

There are three critical components to the switch statement:

• case:
This is the value that is evaluated for equivalence with the argument to the switch
statement.
• default: This is an optional, catch-all expression, should none of the case statements
evaluate to true.
• Abrupt completion of the case statement; usually break: This is required to prevent the
undesired evaluation of further case statements.

With the exception of continue, it is possible to use any statement which would cause the abrupt
completion of a statement. This includes:

• break
• return
• throw

In the example below, a typical switch statement is written with four possible cases, including
default.

Scanner scan = new Scanner(System.in);


int i = scan.nextInt();
switch (i) {
case 0:
System.out.println("i is zero");
break;
case 1:
System.out.println("i is one");
break;
case 2:
System.out.println("i is two");

https://riptutorial.com/ 100
break;
default:
System.out.println("i is less than zero or greater than two");
}

By omitting break or any statement which would an abrupt completion, we can leverage what are
known as "fall-through" cases, which evaluate against several values. This can be used to create
ranges for a value to be successful against, but is still not as flexible as inequalities.

Scanner scan = new Scanner(System.in);


int foo = scan.nextInt();
switch(foo) {
case 1:
System.out.println("I'm equal or greater than one");
case 2:
case 3:
System.out.println("I'm one, two, or three");
break;
default:
System.out.println("I'm not either one, two, or three");
}

In case of foo == 1 the output will be:

I'm equal or greater than one


I'm one, two, or three

In case of foo == 3 the output will be:

I'm one, two, or three

Java SE 5

The switch statement can also be used with enums.

enum Option {
BLUE_PILL,
RED_PILL
}

public void takeOne(Option option) {


switch(option) {
case BLUE_PILL:
System.out.println("Story ends, wake up, believe whatever you want.");
break;
case RED_PILL:
System.out.println("I show you how deep the rabbit hole goes.");
break;

}
}

Java SE 7

The switch statement can also be used with Strings.

https://riptutorial.com/ 101
public void rhymingGame(String phrase) {
switch (phrase) {
case "apples and pears":
System.out.println("Stairs");
break;
case "lorry":
System.out.println("truck");
break;
default:
System.out.println("Don't know any more");
}
}

Ternary Operator

Sometimes you have to check for a condition and set the value of a variable.

For ex.

String name;

if (A > B) {
name = "Billy";
} else {
name = "Jimmy";
}

This can be easily written in one line as

String name = A > B ? "Billy" : "Jimmy";

The value of the variable is set to the value immediately after the condition, if the condition is true.
If the condition is false, the second value will be given to the variable.

Break

The break statement ends a loop (like for, while) or the evaluation of a switch statement.

Loop:

while(true) {
if(someCondition == 5) {
break;
}
}

The loop in the example would run forever. But when someCondition equals 5 at some point of
execution, then the loop ends.

If multiple loops are cascaded, only the most inner loop ends using break.

Try ... Catch ... Finally

https://riptutorial.com/ 102
The try { ... } catch ( ... ) { ... } control structure is used for handling Exceptions.

String age_input = "abc";


try {
int age = Integer.parseInt(age_input);
if (age >= 18) {
System.out.println("You can vote!");
} else {
System.out.println("Sorry, you can't vote yet.");
}
} catch (NumberFormatException ex) {
System.err.println("Invalid input. '" + age_input + "' is not a valid integer.");
}

This would print:

Invalid input. 'abc' is not a valid integer.

A finally clause can be added after the catch. The finally clause would always be executed,
regardless of whether an exception was thrown.

try { ... } catch ( ... ) { ... } finally { ... }

String age_input = "abc";


try {
int age = Integer.parseInt(age_input);
if (age >= 18) {
System.out.println("You can vote!");
} else {
System.out.println("Sorry, you can't vote yet.");
}
} catch (NumberFormatException ex) {
System.err.println("Invalid input. '" + age_input + "' is not a valid integer.");
} finally {
System.out.println("This code will always be run, even if an exception is thrown");
}

This would print:

Invalid input. 'abc' is not a valid integer.


This code will always be run, even if an exception is thrown

Nested break / continue

It's possible to break / continue to an outer loop by using label statements:

outerloop:
for(...) {
innerloop:
for(...) {
if(condition1)
break outerloop;

if(condition2)
continue innerloop; // equivalent to: continue;

https://riptutorial.com/ 103
}
}

There is no other use for labels in Java.

Continue Statement in Java

The continue statement is used to skip the remaining steps in the current iteration and start with
the next loop iteration. The control goes from the continue statement to the step value (increment
or decrement), if any.

String[] programmers = {"Adrian", "Paul", "John", "Harry"};

//john is not printed out


for (String name : programmers) {
if (name.equals("John"))
continue;
System.out.println(name);
}

The continue statement can also make the control of the program shift to the step value (if any) of
a named loop:

Outer: // The name of the outermost loop is kept here as 'Outer'


for(int i = 0; i < 5; )
{
for(int j = 0; j < 5; j++)
{
continue Outer;
}
}

Read Basic Control Structures online: https://riptutorial.com/java/topic/118/basic-control-structures

https://riptutorial.com/ 104
Chapter 14: Benchmarks
Introduction
Writing performance benchmarks in java is not as simple as getting System.currentTimeMillis() in
the beginning and in the end and calculating the difference. To write valid performance
benchmarks, one should use proper tools.

Examples
Simple JMH example

One of the tools for writing proper benchmark tests is JMH. Let's say we want to compare
performance of searching an element in HashSet vs TreeSet.

The easiest way to get JHM into your project - is to use maven and shade plugin. Also you can
see pom.xml from JHM examples.

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>/benchmarks</finalName>
<transformers>
<transformer

implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>

https://riptutorial.com/ 105
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.18</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.18</version>
</dependency>
</dependencies>

After this you need to write benchmark class itself:

package benchmark;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;

@State(Scope.Thread)
public class CollectionFinderBenchmarkTest {
private static final int SET_SIZE = 10000;

private Set<String> hashSet;


private Set<String> treeSet;

private String stringToFind = "8888";

@Setup
public void setupCollections() {
hashSet = new HashSet<>(SET_SIZE);
treeSet = new TreeSet<>();

for (int i = 0; i < SET_SIZE; i++) {


final String value = String.valueOf(i);
hashSet.add(value);
treeSet.add(value);
}

stringToFind = String.valueOf(new Random().nextInt(SET_SIZE));


}

@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public void testHashSet(Blackhole blackhole) {
blackhole.consume(hashSet.contains(stringToFind));
}

@Benchmark

https://riptutorial.com/ 106
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public void testTreeSet(Blackhole blackhole) {
blackhole.consume(treeSet.contains(stringToFind));
}
}

Please keep in mind this blackhole.consume(), we'll get back to it later. Also we need main class for
running benchmark:

package benchmark;

import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

public class BenchmarkMain {


public static void main(String[] args) throws RunnerException {
final Options options = new OptionsBuilder()
.include(CollectionFinderBenchmarkTest.class.getSimpleName())
.forks(1)
.build();

new Runner(options).run();
}
}

And we're all set. We just need to run mvn package (it will create benchmarks.jar in your /target
folder) and run our benchmark test:

java -cp target/benchmarks.jar benchmark.BenchmarkMain

And after some warmup and calculation iterations, we will have our results:

# Run complete. Total time: 00:01:21

Benchmark Mode Cnt Score Error Units


CollectionFinderBenchmarkTest.testHashSet avgt 20 9.940 ± 0.270 ns/op
CollectionFinderBenchmarkTest.testTreeSet avgt 20 98.858 ± 13.743 ns/op

About that blackhole.consume(). If your calculations do not change the state of your application,
java will most likely just ignore it. So, in order to avoid it, you can either make your benchmark
methods return some value, or use Blackhole object to consume it.

You can find more information about writing proper benchmarks in Aleksey Shipilëv's blog, in
Jacob Jenkov's blog and in java-performance blog: 1, 2.

Read Benchmarks online: https://riptutorial.com/java/topic/9514/benchmarks

https://riptutorial.com/ 107
Chapter 15: BigDecimal
Introduction
The BigDecimal class provides operations for arithmetic (add, subtract, multiply, divide), scale
manipulation, rounding, comparison, hashing, and format conversion. The BigDecimal represents
immutable, arbitrary-precision signed decimal numbers. This class shall be used in a necessity of
high-precision calculation.

Examples
BigDecimal objects are immutable

If you want to calculate with BigDecimal you have to use the returned value because BigDecimal
objects are immutable:

BigDecimal a = new BigDecimal("42.23");


BigDecimal b = new BigDecimal("10.001");

a.add(b); // a will still be 42.23

BigDecimal c = a.add(b); // c will be 52.231

Comparing BigDecimals

The method compareTo should be used to compare BigDecimals:

BigDecimal a = new BigDecimal(5);


a.compareTo(new BigDecimal(0)); // a is greater, returns 1
a.compareTo(new BigDecimal(5)); // a is equal, returns 0
a.compareTo(new BigDecimal(10)); // a is less, returns -1

Commonly you should not use the equals method since it considers two BigDecimals equal only if
they are equal in value and also scale:

BigDecimal a = new BigDecimal(5);


a.equals(new BigDecimal(5)); // value and scale are equal, returns true
a.equals(new BigDecimal(5.00)); // value is equal but scale is not, returns false

Mathematical operations with BigDecimal

This example shows how to perform basic mathematical operations using BigDecimals.

1.Addition

https://riptutorial.com/ 108
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

3.Multiplication
When multiplying two BigDecimals the result is going to have scale equal to the sum of the scales
of operands.

BigDecimal a = new BigDecimal("5.11");


BigDecimal b = new BigDecimal("7.221");

//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.

BigDecimal a = new BigDecimal("5.11");


BigDecimal b = new BigDecimal("7.221");

MathContext returnRules = new MathContext(4, RoundingMode.HALF_DOWN);

//Equivalent to result = a * b
BigDecimal result = a.multiply(b, returnRules);
System.out.println(result);

Result : 36.90

https://riptutorial.com/ 109
4.Division
Division is a bit more complicated than the other arithmetic operations, for instance consider the
below example:

BigDecimal a = new BigDecimal("5");


BigDecimal b = new BigDecimal("7");

BigDecimal result = a.divide(b);


System.out.println(result);

We would expect this to give something similar to : 0.7142857142857143, but we would get:

Result: java.lang.ArithmeticException: Non-terminating decimal expansion; no


exact representable decimal result.

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.

For example, I could do:

BigDecimal a = new BigDecimal("5");


BigDecimal b = new BigDecimal("7");

//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

https://riptutorial.com/ 110
BigDecimal a = new BigDecimal("5");

//Equivalent to result = a^10


BigDecimal result = a.pow(10);
System.out.println(result);

Result : 9765625

7.Max
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");

//Equivalent to result = MAX(a,b)


BigDecimal result = a.max(b);
System.out.println(result);

Result : 7

8.Min
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");

//Equivalent to result = MIN(a,b)


BigDecimal result = a.min(b);
System.out.println(result);

Result : 5

9.Move Point To Left


BigDecimal a = new BigDecimal("5234.49843776");

//Moves the decimal point to 2 places left of current position


BigDecimal result = a.movePointLeft(2);
System.out.println(result);

Result : 52.3449843776

10.Move Point To Right


BigDecimal a = new BigDecimal("5234.49843776");

//Moves the decimal point to 3 places right of current position


BigDecimal result = a.movePointRight(3);

https://riptutorial.com/ 111
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.

Using BigDecimal instead of float

Due to way that the float type is represented in computer memory, results of operations using this
type can be inaccurate - some values are stored as approximations. Good examples of this are
monetary calculations. If high precision is necessary, other types should be used. e.g. Java 7
provides BigDecimal.

import java.math.BigDecimal;

public class FloatTest {

public static void main(String[] args) {


float accountBalance = 10000.00f;
System.out.println("Operations using float:");
System.out.println("1000 operations for 1.99");
for(int i = 0; i<1000; i++){
accountBalance -= 1.99f;
}
System.out.println(String.format("Account balance after float operations: %f",
accountBalance));

BigDecimal accountBalanceTwo = new BigDecimal("10000.00");


System.out.println("Operations using BigDecimal:");
System.out.println("1000 operations for 1.99");
BigDecimal operation = new BigDecimal("1.99");
for(int i = 0; i<1000; i++){
accountBalanceTwo = accountBalanceTwo.subtract(operation);
}
System.out.println(String.format("Account balance after BigDecimal operations: %f",
accountBalanceTwo));
}

Output of this program is:

Operations using float:


1000 operations for 1.99
Account balance after float operations: 8009,765625
Operations using BigDecimal:
1000 operations for 1.99
Account balance after BigDecimal operations: 8010,000000

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.

https://riptutorial.com/ 112
BigDecimal.valueOf()

The BigDecimal class contains an internal cache of frequently used numbers e.g. 0 to 10. The
BigDecimal.valueOf() methods are provided in preference to constructors with similar type
parameters i.e. in the below example a is preferred to b.

BigDecimal a = BigDecimal.valueOf(10L); //Returns cached Object reference


BigDecimal b = new BigDecimal(10L); //Does not return cached Object reference

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)
BigDecimal b = new BigDecimal(15.15); //Return unpredictable result

Initialization of BigDecimals with value zero, one or ten

BigDecimal provides static properties for the numbers zero, one and ten. It's good practise to use
these instead of using the actual numbers:

• 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;

Read BigDecimal online: https://riptutorial.com/java/topic/1667/bigdecimal

https://riptutorial.com/ 113
Chapter 16: BigInteger
Introduction
The BigInteger class is used for mathematical operations involving large integers with magnitudes
too large for primitive data types. For example 100-factorial is 158 digits - much larger than a long
can represent. BigInteger provides analogues to all of Java's primitive integer operators, and all
relevant methods from java.lang.Math as well as few other operations.

Syntax
• BigInteger variable_name = new BigInteger("12345678901234567890"); // a decimal integer
as a string
• BigInteger variable_name = new
BigInteger("1010101101010100101010011000110011101011000111110000101011010010",
2) // a binary integer as a string
• BigInteger variable_name = new BigInteger("ab54a98ceb1f0800", 16) // a hexadecimal
integer as a string
• BigInteger variable_name = new BigInteger(64, new Random()); // a pseudorandom number
generator supplying 64 bits to construct an integer
• BigInteger variable_name = new BigInteger(new byte[]{0, -85, 84, -87, -116, -21, 31, 10, -
46}); // signed two's complement representation of an integer (big endian)
• BigInteger variable_name = new BigInteger(1, new byte[]{-85, 84, -87, -116, -21, 31, 10, -
46}); // unsigned two's complement representation of a positive integer (big endian)

Remarks
BigIntegeris immutable. Therefore you can't change its state. For example, the following won't
work as sum won't be updated due to immutability.

BigInteger sum = BigInteger.ZERO;


for(int i = 1; i < 5000; i++) {
sum.add(BigInteger.valueOf(i));
}

Assign the result to the sum variable to make it work.

sum = sum.add(BigInteger.valueOf(i));

Java SE 8

The official documentation of BigInteger states that BigInteger implementations should support all
integers between -22147483647 and 22147483647 (exclusive). This means BigIntegers can have
more than 2 billion bits!

https://riptutorial.com/ 114
Examples
Initialization

The java.math.BigInteger class provides operations analogues to all of Java's primitive integer
operators and for all relevant methods from java.lang.Math. As the java.math package is not
automatically made available you may have to import java.math.BigInteger before you can use the
simple class name.

To convert long or int values to BigInteger use:

long longValue = Long.MAX_VALUE;


BigInteger valueFromLong = BigInteger.valueOf(longValue);

or, for integers:

int intValue = Integer.MIN_VALUE; // negative


BigInteger valueFromInt = BigInteger.valueOf(intValue);

which will widen the intValue integer to long, using sign bit extension for negative values, so that
negative values will stay negative.

To convert a numeric String to BigInteger use:

String decimalString = "-1";


BigInteger valueFromDecimalString = new BigInteger(decimalString);

Following constructor is used to translate the String representation of a BigInteger in the specified
radix into a BigInteger.

String binaryString = "10";


int binaryRadix = 2;
BigInteger valueFromBinaryString = new BigInteger(binaryString , binaryRadix);

Java also supports direct conversion of bytes to an instance of BigInteger. Currently only signed
and unsigned big endian encoding may be used:

byte[] bytes = new byte[] { (byte) 0x80 };


BigInteger valueFromBytes = new BigInteger(bytes);

This will generate a BigInteger instance with value -128 as the first bit is interpreted as the sign bit.

byte[] unsignedBytes = new byte[] { (byte) 0x80 };


int sign = 1; // positive
BigInteger valueFromUnsignedBytes = new BigInteger(sign, unsignedBytes);

This will generate a BigInteger instance with value 128 as the bytes are interpreted as unsigned

https://riptutorial.com/ 115
number, and the sign is explicitly set to 1, a positive number.

There are predefined constants for common values:

• BigInteger.ZERO— value of "0".


• BigInteger.ONE — value of "1".
• BigInteger.TEN — value of "10".

There's also BigInteger.TWO (value of "2"), but you can't use it in your code because it's private.

Comparing BigIntegers

You can compare BigIntegers same as you compare String or other objects in Java.

For example:

BigInteger one = BigInteger.valueOf(1);


BigInteger two = BigInteger.valueOf(2);

if(one.equals(two)){
System.out.println("Equal");
}
else{
System.out.println("Not Equal");
}

Output:

Not Equal

Note:

In general, do not use use the == operator to compare BigIntegers

• == operator: compares references; i.e. whether two values refer to the same object
• equals() method: compares the content of two BigIntegers.

For example, BigIntegers should not be compared in the following way:

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:

https://riptutorial.com/ 116
BigInteger reallyBig = BigInteger.valueOf(1);
if(BigInteger.ONE.equals(reallyBig)){
//code when they are equal.
}

You can also compare two BigIntegers by using compareTo() method, as following: compareTo()
returns 3 values.

• 0: When both are equal.


• 1: When first is greater than second (the one in brackets).
• -1: When first is less than second.

BigInteger reallyBig = BigInteger.valueOf(10);


BigInteger reallyBig1 = BigInteger.valueOf(100);

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.
}

BigInteger Mathematical Operations Examples

BigInteger is in an immutable object, so you need to assign the results of any mathematical
operation, to a new BigInteger instance.

Addition: 10 + 10 = 20

BigInteger value1 = new BigInteger("10");


BigInteger value2 = new BigInteger("10");

BigInteger sum = value1.add(value2);


System.out.println(sum);

output: 20

Substraction: 10 - 9 = 1

BigInteger value1 = new BigInteger("10");


BigInteger value2 = new BigInteger("9");

BigInteger sub = value1.subtract(value2);


System.out.println(sub);

output: 1

Division: 10 / 5 = 2

https://riptutorial.com/ 117
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("5");

BigInteger div = value1.divide(value2);


System.out.println(div);

output: 2

Division: 17/4 = 4

BigInteger value1 = new BigInteger("17");


BigInteger value2 = new BigInteger("4");

BigInteger div = value1.divide(value2);


System.out.println(div);

output: 4

Multiplication: 10 * 5 = 50

BigInteger value1 = new BigInteger("10");


BigInteger value2 = new BigInteger("5");

BigInteger mul = value1.multiply(value2);


System.out.println(mul);

output: 50

Power: 10 ^ 3 = 1000

BigInteger value1 = new BigInteger("10");


BigInteger power = value1.pow(3);
System.out.println(power);

output: 1000

Remainder: 10 % 6 = 4

BigInteger value1 = new BigInteger("10");


BigInteger value2 = new BigInteger("6");

BigInteger power = value1.remainder(value2);


System.out.println(power);

output: 4

GCD: Greatest Common Divisor (GCD) for 12and 18 is 6.

BigInteger value1 = new BigInteger("12");


BigInteger value2 = new BigInteger("18");

System.out.println(value1.gcd(value2));

https://riptutorial.com/ 118
Output: 6

Maximum of two BigIntegers:

BigInteger value1 = new BigInteger("10");


BigInteger value2 = new BigInteger("11");

System.out.println(value1.max(value2));

Output: 11

Minimum of two BigIntegers:

BigInteger value1 = new BigInteger("10");


BigInteger value2 = new BigInteger("11");

System.out.println(value1.min(value2));

Output: 10

Binary Logic Operations on BigInteger

BigInteger supports the binary logic operations that are available to Number types as well. As with
all operations they are implemented by calling a method.

Binary Or:

BigInteger val1 = new BigInteger("10");


BigInteger val2 = new BigInteger("9");

val1.or(val2);

Output: 11 (which is equivalent to 10 | 9)

Binary And:

BigInteger val1 = new BigInteger("10");


BigInteger val2 = new BigInteger("9");

val1.and(val2);

Output: 8 (which is equivalent to 10 & 9)

Binary Xor:

BigInteger val1 = new BigInteger("10");


BigInteger val2 = new BigInteger("9");

val1.xor(val2);

Output: 3 (which is equivalent to 10 ^ 9)

https://riptutorial.com/ 119
RightShift:

BigInteger val1 = new BigInteger("10");

val1.shiftRight(1); // the argument be an Integer

Output: 5 (equivalent to 10 >> 1)

LeftShift:

BigInteger val1 = new BigInteger("10");

val1.shiftLeft(1); // here parameter should be Integer

Output: 20 (equivalent to 10 << 1)

Binary Inversion (Not):

BigInteger val1 = new BigInteger("10");

val1.not();

Output: 5

NAND (And-Not):*

BigInteger val1 = new BigInteger("10");


BigInteger val2 = new BigInteger("9");

val1.andNot(val2);

Output: 7

Generating random BigIntegers

The BigInteger class has a constructor dedicated to generate random BigIntegers, given an
instance of java.util.Random and an int that specifies how many bits will the BigInteger have. Its
usage is quite simple - when you call the constructor BigInteger(int, Random) like this:

BigInteger randomBigInt = new BigInteger(bitCount, sourceOfRandomness);

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:

https://riptutorial.com/ 120
new BigInteger(32, new Random());

If you're willing to give up speed for higher-quality random numbers, you can use a new
SecureRandom() instead:

import java.security.SecureRandom;

// somewhere in the code...


new BigInteger(32, new SecureRandom());

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.

new BigInteger(32, new Random() {


int seed = 0;

@Override
protected int next(int bits) {
seed = ((22695477 * seed) + 1) & 2147483647; // Values shamelessly stolen from
Wikipedia
return seed;
}
});

Read BigInteger online: https://riptutorial.com/java/topic/1514/biginteger

https://riptutorial.com/ 121
Chapter 17: Bit Manipulation
Remarks
• Unlike C/C++, Java is completely endian-neutral with respect to the underlying machine
hardware. You do not get big or little endian behavior by default; you have to explicitly
specify which behavior you want.

• The byte type is signed, with the range -128 to +127. To convert a byte value to its unsigned
equivalent, mask it with 0xFF like this: (b & 0xFF).

Examples
Packing / unpacking values as bit fragments

It is common for memory performance to compress multiple values into a single primitive value.
This may be useful to pass various information into a single variable.

For example, one can pack 3 bytes - such as color code in RGB - into an single int.

Packing the values

// Raw bytes as input


byte[] b = {(byte)0x65, (byte)0xFF, (byte)0x31};

// Packed in big endian: x == 0x65FF31


int x = (b[0] & 0xFF) << 16 // Red
| (b[1] & 0xFF) << 8 // Green
| (b[2] & 0xFF) << 0; // Blue

// Packed in little endian: y == 0x31FF65


int y = (b[0] & 0xFF) << 0
| (b[1] & 0xFF) << 8
| (b[2] & 0xFF) << 16;

Unpacking the values

// Raw int32 as input


int x = 0x31FF65;

// Unpacked in big endian: {0x65, 0xFF, 0x31}


byte[] c = {
(byte)(x >> 16),
(byte)(x >> 8),
(byte)(x & 0xFF)
};

// Unpacked in little endian: {0x31, 0xFF, 0x65}


byte[] d = {
(byte)(x & 0xFF),
(byte)(x >> 8),

https://riptutorial.com/ 122
(byte)(x >> 16)
};

Checking, setting, clearing, and toggling individual bits. Using long as bit
mask

Assuming we want to modify bit n of an integer primitive, i (byte, short, char, int, or long):

(i & 1 << n) != 0 // checks bit 'n'


i |= 1 << n; // sets bit 'n' to 1
i &= ~(1 << n); // sets bit 'n' to 0
i ^= 1 << n; // toggles the value of bit 'n'

Using long/int/short/byte as a bit mask:

public class BitMaskExample {


private static final long FIRST_BIT = 1L << 0;
private static final long SECOND_BIT = 1L << 1;
private static final long THIRD_BIT = 1L << 2;
private static final long FOURTH_BIT = 1L << 3;
private static final long FIFTH_BIT = 1L << 4;
private static final long BIT_55 = 1L << 54;

public static void main(String[] args) {


checkBitMask(FIRST_BIT | THIRD_BIT | FIFTH_BIT | BIT_55);
}

private static void checkBitMask(long bitmask) {


System.out.println("FIRST_BIT: " + ((bitmask & FIRST_BIT) != 0));
System.out.println("SECOND_BIT: " + ((bitmask & SECOND_BIT) != 0));
System.out.println("THIRD_BIT: " + ((bitmask & THIRD_BIT) != 0));
System.out.println("FOURTh_BIT: " + ((bitmask & FOURTH_BIT) != 0));
System.out.println("FIFTH_BIT: " + ((bitmask & FIFTH_BIT) != 0));
System.out.println("BIT_55: " + ((bitmask & BIT_55) != 0));
}
}

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.

Expressing the power of 2

For expressing the power of 2 (2^n) of integers, one may use a bitshift operation that allows to
explicitly specify the n.

https://riptutorial.com/ 123
The syntax is basically:

int pow2 = 1<<n;

Examples:

int twoExp4 = 1<<4; //2^4


int twoExp5 = 1<<5; //2^5
int twoExp6 = 1<<6; //2^6
...
int twoExp31 = 1<<31; //2^31

This is especially useful when defining constant values that should make it apparent, that a power
of 2 is used, instead of using hexadecimal or decimal values.

int twoExp4 = 0x10; //hexadecimal


int twoExp5 = 0x20; //hexadecimal
int twoExp6 = 64; //decimal
...
int twoExp31 = -2147483648; //is that a power of 2?

A simple method to calculate the int power of 2 would be

int pow2(int exp){


return 1<<exp;
}

Checking if a number is a power of 2

If an integer x is a power of 2, only one bit is set, whereas x-1 has all bits set after that. For
example: 4 is 100 and 3 is 011 as binary number, which satisfies the aforementioned condition. Zero
is not a power of 2 and has to be checked explicitly.

boolean isPowerOfTwo(int x)
{
return (x != 0) && ((x & (x - 1)) == 0);
}

Usage for Left and Right Shift

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)

RESOURCE = READ WRITE EXECUTE (12 bit number)

RESOURCE = 0100 0110 0101 = 4 6 5 (12 bit number)

How can we get the (12 bit number) permissions, set on above (12 bit number)?

0100 0110 0101

https://riptutorial.com/ 124
0000 0000 0111 (&)

0000 0000 0101 = 5

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?

0100 0110 0101

0111 0000 0000 (&)

0100 0000 0000 = 1024

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)

We now actually have the READ permissions which is 4.

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

If you are thinking that we will simply do:

READ | WRITE | EXECUTE,


you are somewhat right but not exactly. See, what will happen if we will
perform READ | WRITE | EXECUTE

0001 | 0100 | 0110 => 0111

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.

(READ << 8) | (WRITE << 4) | (EXECUTE)

0000 0000 0001 << 8 (READ)

https://riptutorial.com/ 125
0001 0000 0000 (Left shift by 8 bits)

0000 0000 0100 << 4 (WRITE)

0000 0100 0000 (Left shift by 4 bits)

0000 0000 0001 (EXECUTE)

Now if we add the results of above shifting, it will be something like;

0001 0000 0000 (READ)

0000 0100 0000 (WRITE)

0000 0000 0001 (EXECUTE)

0001 0100 0001 (PERMISSIONS)

java.util.BitSet class

Since 1.7 there's a java.util.BitSet class that provides simple and user-friendly bit storage and
manipulation interface:

final BitSet bitSet = new BitSet(8); // by default all bits are unset

IntStream.range(0, 8).filter(i -> i % 2 == 0).forEach(bitSet::set); // {0, 2, 4, 6}

bitSet.set(3); // {0, 2, 3, 4, 6}

bitSet.set(3, false); // {0, 2, 4, 6}

final boolean b = bitSet.get(3); // b = false

bitSet.flip(6); // {0, 2, 4}

bitSet.set(100); // {0, 2, 4, 100} - expands automatically

BitSet implements Clonable and Serializable, and under the hood all bit values are stored in long[]
words field, that expands automatically.

It also supports whole-set logical operations and, or, xor, andNot:

bitSet.and(new BitSet(8));
bitSet.or(new BitSet(8));
bitSet.xor(new BitSet(8));
bitSet.andNot(new BitSet(8));

Signed vs unsigned shift

In Java, all number primitives are signed. For example, an int always represent values from [-2^31
- 1, 2^31], keeping the first bit to sign the value - 1 for negative value, 0 for positive.

https://riptutorial.com/ 126
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.

initial value: 4 ( 100)


signed left-shift: 4 << 1 8 ( 1000)
signed right-shift: 4 >> 1 2 ( 10)
unsigned right-shift: 4 >>> 1 2 ( 10)
initial value: -4 ( 11111111111111111111111111111100)
signed left-shift: -4 << 1 -8 ( 11111111111111111111111111111000)
signed right-shift: -4 >> 1 -2 ( 11111111111111111111111111111110)
unsigned right-shift: -4 >>> 1 2147483646 ( 1111111111111111111111111111110)

Why is there no <<< ?

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.

See this question for a more detailled answer.

Read Bit Manipulation online: https://riptutorial.com/java/topic/1177/bit-manipulation

https://riptutorial.com/ 127
Chapter 18: BufferedWriter
Syntax
• new BufferedWriter(Writer); //The default constructor
• BufferedWriter.write(int c); //Writes a single character
• BufferedWriter.write(String str); //Writes a string
• BufferedWriter.newLine(); //Writes a line separator
• BufferedWriter.close(); //Closes the BufferedWriter

Remarks
• If you try to write from a BufferedWriter (using BufferedWriter.write()) after closing the
BufferedWriter (using BufferedWriter.close()), it will throw an IOException.
• The BufferedWriter(Writer) constructor does NOT throw an IOException. However, the
FileWriter(File) constructor throws a FileNotFoundException, which extends IOException. So
catching IOException will also catch FileNotFoundException, there is never a need for a second
catch statement unless you plan on doing something different with the FileNotFoundException.

Examples
Write a line of text to File

This code writes the string to a file. It is important to close the writer, so this is done in a finally
block.

public void writeLineToFile(String str) throws IOException {


File file = new File("file.txt");
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(file));
bw.write(str);
} finally {
if (bw != null) {
bw.close();
}
}
}

Also note that write(String s) does not place newline character after string has been written. To
put it use newLine() method.

Java SE 7

Java 7 adds the java.nio.file package, and try-with-resources:

public void writeLineToFile(String str) throws IOException {

https://riptutorial.com/ 128
Path path = Paths.get("file.txt");
try (BufferedWriter bw = Files.newBufferedWriter(path)) {
bw.write(str);
}
}

Read BufferedWriter online: https://riptutorial.com/java/topic/3063/bufferedwriter

https://riptutorial.com/ 129
Chapter 19: ByteBuffer
Introduction
The ByteBuffer class was introduced in java 1.4 to ease working on binary data. It's especially
suited to use with primitive type data. It allows the creation, but also subsequent manipulation of a
byte[]s on a higher abstraction level

Syntax
• byte[] arr = new byte[1000];
• ByteBuffer buffer = ByteBuffer.wrap(arr);
• ByteBuffer buffer = ByteBuffer.allocate(1024);
• ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
• byte b = buffer.get();
• byte b = buffer.get(10);
• short s = buffer.getShort(10);
• buffer.put((byte) 120);
• buffer.putChar('a');

Examples
Basic Usage - Creating a ByteBuffer

There's two ways to create a ByteBuffer, where one can be subdivided again.

If you have an already existing byte[], you can "wrap" it into a ByteBuffer to simplify processing:

byte[] reqBuffer = new byte[BUFFER_SIZE];


int readBytes = socketInputStream.read(reqBuffer);
final ByteBuffer reqBufferWrapper = ByteBuffer.wrap(reqBuffer);

This would be a possibility for code that handles low-level networking interactions

If you do not have an already existing byte[], you can create a ByteBuffer over an array that's
specifically allocated for the buffer like this:

final ByteBuffer respBuffer = ByteBuffer.allocate(RESPONSE_BUFFER_SIZE);


putResponseData(respBuffer);
socketOutputStream.write(respBuffer.array());

If the code-path is extremely performance critical and you need direct system memory access,
the ByteBuffer can even allocate direct buffers using #allocateDirect()

https://riptutorial.com/ 130
Basic Usage - Write Data to the Buffer

Given a ByteBuffer instance one can write primitive-type data to it using relative and absolute put.
The striking difference is that putting data using the relative method keeps track of the index the
data is inserted at for you, while the absolute method always requires giving an index to put the
data at.

Both methods allow "chaining" calls. Given a sufficiently sized buffer one can accordingly do the
following:

buffer.putInt(0xCAFEBABE).putChar('c').putFloat(0.25).putLong(0xDEADBEEFCAFEBABE);

which is equivalent to:

buffer.putInt(0xCAFEBABE);
buffer.putChar('c');
buffer.putFloat(0.25);
buffer.putLong(0xDEADBEEFCAFEBABE);

Do note that the method operating on bytes is not named specially. Additionally note that it's also
valid to pass both a ByteBuffer and a byte[] to put. Other than that, all primitive types have
specialized put-methods.

An additional note: The index given when using absolute put* is always counted in bytes.

Basic Usage - Using DirectByteBuffer

DirectByteBuffer is special implementation of ByteBuffer that has no byte[] laying underneath.

We can allocate such ByteBuffer by calling:

ByteBuffer directBuffer = ByteBuffer.allocateDirect(16);

This operation will allocate 16 bytes of memory. The contents of direct buffers may reside outside
of the normal garbage-collected heap.

We can verify whether ByteBuffer is direct by calling:

directBuffer.isDirect(); // true

The main characteristics of DirectByteBuffer is that JVM will try to natively work on allocated
memory without any additional buffering so operations performed on it may be faster then those
performed on ByteBuffers with arrays lying underneath.

It is recomended to use DirectByteBuffer with heavy IO operations that rely on speed of execution,
like real time communication.

We have to be aware that if we try using array() method we will get UnsupportedOperationException.

https://riptutorial.com/ 131
So it is a good practice to chech whether our ByteBuffer has it (byte array) before we try to access
it:

byte[] arrayOfBytes;
if(buffer.hasArray()) {
arrayOfBytes = buffer.array();
}

Another use of direct byte buffer is interop through JNI. Since a direct byte buffer does not use a
byte[], but an actual block of memory, it is possible to access that memory directly through a
pointer in native code. This can save a bit of trouble and overhead on marshalling between the
Java and native representation of data.

The JNI interface defines several functions to handle direct byte buffers: NIO Support.

Read ByteBuffer online: https://riptutorial.com/java/topic/702/bytebuffer

https://riptutorial.com/ 132
Chapter 20: Bytecode Modification
Examples
What is Bytecode?

Bytecode is the set of instructions used by the JVM. To illustrate this let's take this Hello World
program.

public static void main(String[] args){


System.out.println("Hello World");
}

This is what it turns into when compiled into bytecode.

public static main([Ljava/lang/String; args)V


getstatic java/lang/System out Ljava/io/PrintStream;
ldc "Hello World"
invokevirtual java/io/PrintStream print(Ljava/lang/String;)V

What's the logic behind this?


getstatic - Retreives the value of a static field of a class. In this case, the PrintStream "Out" of
System.

ldc - Push a constant onto the stack. In this case, the String "Hello World"

invokevirtual - Invokes a method on a loaded reference on the stack and puts the result on the
stack. Parameters of the method are also taken from the stack.

Well, there has to be more right?


There are 255 opcodes, but not all of them are implemented yet. A table with all of the current
opcodes can be found here: Java bytecode instruction listings.

How can I write / edit bytecode?


There's multiple ways to write and edit bytecode. You can use a compiler, use a library, or use a
program.

For writing:

• Jasmin

https://riptutorial.com/ 133
• Krakatau

For editing:

• Libraries
○ASM
○Javassist
○BCEL - Doesn't support Java 8+
• Tools
○Bytecode-Viewer
○JBytedit
○reJ - Doesn't support Java 8+
○JBE - Doesn't support Java 8+

I'd like to learn more about bytecode!


There's probably a specific documentation page specificially for bytecode. This page focuses on
the modification of bytecode using different libraries and tools.

How to edit jar files with ASM

Firstly the classes from the jar need to be loaded. We'll use three methods for this process:

• loadClasses(File)
• readJar(JarFile, JarEntry, Map)
• getNode(byte[])

Map<String, ClassNode> loadClasses(File jarFile) throws IOException {


Map<String, ClassNode> classes = new HashMap<String, ClassNode>();
JarFile jar = new JarFile(jarFile);
Stream<JarEntry> str = jar.stream();
str.forEach(z -> readJar(jar, z, classes));
jar.close();
return classes;
}

Map<String, ClassNode> readJar(JarFile jar, JarEntry entry, Map<String, ClassNode> classes) {


String name = entry.getName();
try (InputStream jis = jar.getInputStream(entry)){
if (name.endsWith(".class")) {
byte[] bytes = IOUtils.toByteArray(jis);
String cafebabe = String.format("%02X%02X%02X%02X", bytes[0], bytes[1], bytes[2],
bytes[3]);
if (!cafebabe.toLowerCase().equals("cafebabe")) {
// This class doesn't have a valid magic
return classes;
}
try {
ClassNode cn = getNode(bytes);
classes.put(cn.name, cn);
} catch (Exception e) {
e.printStackTrace();

https://riptutorial.com/ 134
}
}
} catch (IOException e) {
e.printStackTrace();
}
return classes;
}

ClassNode getNode(byte[] bytes) {


ClassReader cr = new ClassReader(bytes);
ClassNode cn = new ClassNode();
try {
cr.accept(cn, ClassReader.EXPAND_FRAMES);
} catch (Exception e) {
e.printStackTrace();
}
cr = null;
return cn;
}

With these methods loading and changing a jar file becomes a simple matter of changing
ClassNodes in a map. In this example we will replace all Strings in the jar with capitalized ones
using the Tree API.

File jarFile = new File("sample.jar");


Map<String, ClassNode> nodes = loadClasses(jarFile);
// Iterate ClassNodes
for (ClassNode cn : nodes.values()){
// Iterate methods in class
for (MethodNode mn : cn.methods){
// Iterate instructions in method
for (AbstractInsnNode ain : mn.instructions.toArray()){
// If the instruction is loading a constant value
if (ain.getOpcode() == Opcodes.LDC){
// Cast current instruction to Ldc
// If the constant is a string then capitalize it.
LdcInsnNode ldc = (LdcInsnNode) ain;
if (ldc.cst instanceof String){
ldc.cst = ldc.cst.toString().toUpperCase();
}
}
}
}
}

Now that all of the ClassNode's strings have been modified we need to save the changes. In order
to save the changes and have a working output a few things have to be done:

• Export ClassNodes to bytes


• Load non-class jar entries (Ex: Manifest.mf / other binary resources in jar) as bytes
• Save all bytes to a new jar

From the last portion above, we'll create three methods.

• processNodes(Map<String, ClassNode> nodes)


• loadNonClasses(File jarFile)

https://riptutorial.com/ 135
• saveAsJar(Map<String, byte[]> outBytes, String fileName)

Usage:

Map<String, byte[]> out = process(nodes, new HashMap<String, MappedClass>());


out.putAll(loadNonClassEntries(jarFile));
saveAsJar(out, "sample-edit.jar");

The methods used:

static Map<String, byte[]> processNodes(Map<String, ClassNode> nodes, Map<String, MappedClass>


mappings) {
Map<String, byte[]> out = new HashMap<String, byte[]>();
// Iterate nodes and add them to the map of <Class names , Class bytes>
// Using Compute_Frames ensures that stack-frames will be re-calculated automatically
for (ClassNode cn : nodes.values()) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
out.put(mappings.containsKey(cn.name) ? mappings.get(cn.name).getNewName() : cn.name,
cw.toByteArray());
}
return out;
}

static Map<String, byte[]> loadNonClasses(File jarFile) throws IOException {


Map<String, byte[]> entries = new HashMap<String, byte[]>();
ZipInputStream jis = new ZipInputStream(new FileInputStream(jarFile));
ZipEntry entry;
// Iterate all entries
while ((entry = jis.getNextEntry()) != null) {
try {
String name = entry.getName();
if (!name.endsWith(".class") && !entry.isDirectory()) {
// Apache Commons - byte[] toByteArray(InputStream input)
//
// Add each entry to the map <Entry name , Entry bytes>
byte[] bytes = IOUtils.toByteArray(jis);
entries.put(name, bytes);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
jis.closeEntry();
}
}
jis.close();
return entries;
}

static void saveAsJar(Map<String, byte[]> outBytes, String fileName) {


try {
// Create jar output stream
JarOutputStream out = new JarOutputStream(new FileOutputStream(fileName));
// For each entry in the map, save the bytes
for (String entry : outBytes.keySet()) {
// Appent class names to class entries
String ext = entry.contains(".") ? "" : ".class";
out.putNextEntry(new ZipEntry(entry + ext));
out.write(outBytes.get(entry));
out.closeEntry();

https://riptutorial.com/ 136
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}

That's it. All the changes will be saved to "sample-edit.jar".

How to load a ClassNode as a Class

/**
* Load a class by from a ClassNode
*
* @param cn
* ClassNode to load
* @return
*/
public static Class<?> load(ClassNode cn) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
return new ClassDefiner(ClassLoader.getSystemClassLoader()).get(cn.name.replace("/", "."),
cw.toByteArray());
}

/**
* Classloader that loads a class from bytes.
*/
static class ClassDefiner extends ClassLoader {
public ClassDefiner(ClassLoader parent) {
super(parent);
}

public Class<?> get(String name, byte[] bytes) {


Class<?> c = defineClass(name, bytes, 0, bytes.length);
resolveClass(c);
return c;
}
}

How to rename classes in a jar file

public static void main(String[] args) throws Exception {


File jarFile = new File("Input.jar");
Map<String, ClassNode> nodes = JarUtils.loadClasses(jarFile);

Map<String, byte[]> out = JarUtils.loadNonClassEntries(jarFile);


Map<String, String> mappings = new HashMap<String, String>();
mappings.put("me/example/ExampleClass", "me/example/ExampleRenamed");
out.putAll(process(nodes, mappings));
JarUtils.saveAsJar(out, "Input-new.jar");
}

static Map<String, byte[]> process(Map<String, ClassNode> nodes, Map<String, String> mappings)


{
Map<String, byte[]> out = new HashMap<String, byte[]>();
Remapper mapper = new SimpleRemapper(mappings);
for (ClassNode cn : nodes.values()) {

https://riptutorial.com/ 137
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
ClassVisitor remapper = new ClassRemapper(cw, mapper);
cn.accept(remapper);
out.put(mappings.containsKey(cn.name) ? mappings.get(cn.name) : cn.name,
cw.toByteArray());
}
return out;
}

SimpleRemapper is an existing class in the ASM library. However it only allows for class names to
be changed. If you wish to rename fields and methods you should create your own implemenation
of the Remapper class.

Javassist Basic

Javassist is a bytecode instrumentation library that allows you to modify bytecode injecting Java
code that will be converted to bytecode by Javassist and added to the instrumented class/method
at runtime.

Lets write the first transformer that actually take an hypothetical class
"com.my.to.be.instrumented.MyClass" and add to the instructions of each method a log call.

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;

public class DynamicTransformer implements ClassFileTransformer {

public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined,


ProtectionDomain protectionDomain, byte[] classfileBuffer) throws
IllegalClassFormatException {

byte[] byteCode = classfileBuffer;

// into the transformer will arrive every class loaded so we filter


// to match only what we need
if (className.equals("com/my/to/be/instrumented/MyClass")) {

try {
// retrive default Javassist class pool
ClassPool cp = ClassPool.getDefault();
// get from the class pool our class with this qualified name
CtClass cc = cp.get("com.my.to.be.instrumented.MyClass");
// get all the methods of the retrieved class
CtMethod[] methods = cc.getDeclaredMethods()
for(CtMethod meth : methods) {
// The instrumentation code to be returned and injected
final StringBuffer buffer = new StringBuffer();
String name = meth.getName();
// just print into the buffer a log for example
buffer.append("System.out.println(\"Method " + name + " executed\" );");
meth.insertBefore(buffer.toString())
}
// create the byteclode of the class

https://riptutorial.com/ 138
byteCode = cc.toBytecode();
// remove the CtClass from the ClassPool
cc.detach();
} catch (Exception ex) {
ex.printStackTrace();
}
}

return byteCode;
}
}

Now in order to use this transformer (so that our JVM will call the method transform on each class
at load time) we need to add this instrumentor this with an agent:

import java.lang.instrument.Instrumentation;

public class EasyAgent {

public static void premain(String agentArgs, Instrumentation inst) {

// registers the transformer


inst.addTransformer(new DynamicTransformer());
}
}

Last step to start our first instrumentor experiment is to actually register this agent class to the
JVM machine execution. The easiest way to actually do it is to register it with an option into the
shell command:

java -javaagent:myAgent.jar MyJavaApplication

As we can see the agent/transformer project is added as a jar to the execution of any application
named MyJavaApplication that is supposed to contain a class named
"com.my.to.be.instrumented.MyClass" to actually execute our injected code.

Read Bytecode Modification online: https://riptutorial.com/java/topic/3747/bytecode-modification

https://riptutorial.com/ 139
Chapter 21: C++ Comparison
Introduction
Java and C++ are similar languages. This topic serves as a quick reference guide for Java and
C++ Engineers.

Remarks

Classes Defined within Other Constructs#

Defined within Another Class


C++
Nested Class[ref] (needs a reference to enclosing class)

class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}

private:
Outer* outer;
};
};

Java
[non-static] Nested Class (aka Inner Class or Member Class)

class OuterClass {
...
class InnerClass {
...
}
}

Statically Defined within Another Class


C++

https://riptutorial.com/ 140
Static Nested Class

class Outer {
class Inner {
...
};
};

Java
Static Nested Class (aka Static Member Class)[ref]

class OuterClass {
...
static class StaticNestedClass {
...
}
}

Defined within a Method


(e.g. event handling)

C++
Local Class[ref]

void fun() {
class Test {
/* members of Test class */
};
}

See also Lambda expressions

Java
Local Class[ref]

class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}

https://riptutorial.com/ 141
Overriding vs Overloading
The following Overriding vs Overloading points apply to both C++ and Java:

• An overridden method has the same name and arguments as its base method.
• An overloaded method has the same name but different arguments and does not rely on
inheritance.
• Two methods with the same name and arguments but different return type are illegal. See
related Stackoverflow questions about "overloading with different return type in Java" -
Question 1; Question 2

Polymorphism
Polymorphism is the ability for objects of different classes related by inheritance to respond
differently to the same method call. Here's an example:

• base class Shape with area as an abstract method


• two derived classes, Square and Circle, implement area methods
• Shape reference points to Square and area is invoked

In C++, polymorphism is enabled by virtual methods. In Java, methods are virtual by default.

Order of Construction/Destruction

Object Cleanup
In C++, it's a good idea to declare a destructor as virtual to ensure that the subclass' destructor will
be called if the base-class pointer is deleted.

In Java, a finalize method is similar a destructor in C++; however, finalizers are unpredictable
(they rely on GC). Best practice - use a "close" method to explicitly cleanup.

protected void close() {


try {
// do subclass cleanup
}
finally {
isClosed = true;
super.close();
}
}

protected void finalize() {


try {
if(!isClosed) close();
}

https://riptutorial.com/ 142
finally {
super.finalize();
}
}

Abstract Methods & Classes


Concept C++ Java

Abstract Method
declared without an pure virtual method abstract method
virtual void eat(void) = 0; abstract void draw();
implementation

Abstract Class cannot be instantiated; has at cannot be instantiated; can have


cannot be least 1 pure virtual method non-abstract methods
class AB {public: virtual void
instantiated f() = 0;};
abstract class GraphicObject {}

no "interface" keyword, but can very similar to abstract class, but


Interface 1) supports multiple inheritance;
mimic a Java interface with
no instance fields 2) no instance fields
facilities of an abstract class
interface TestInterface {}

Accessibility Modifiers
Modifier C++ Java

Public - accessible
no special notes no special notes
by all

Protected -
also accessible within
accessible by also accessible by friends
same package
subclasses

Private - accessible
also accessible by friends no special notes
by members

class default is private; struct default is accessible by all classes


default
public within the same package

Friend - a way to grant access to private


other & protected members without inheritance
(see below)

C++ Friend Example

https://riptutorial.com/ 143
class Node {
private:
int key; Node *next;
// LinkedList::search() can access "key" & "next"
friend int LinkedList::search();
};

The Dreaded Diamond Problem


The diamond problem is an ambiguity that arises when two classes B and C inherit
from A, and class D inherits from both B and C. If there is a method in A that B and C
have overridden, and D does not override it, then which version of the method does D
inherit: that of B, or that of C? (from Wikipedia)

While C++ has always been susceptible to the diamond problem, Java was susceptible until Java
8. Originally, Java didn't support multiple inheritance, but with the advent of default interface
methods, Java classes can not inherit "implementation" from more than one class.

java.lang.Object Class
In Java all classes inherit, either implicitly or explicitly, from the Object class. Any Java reference
can be cast to the Object type.

C++ doesn't have a comparable "Object" class.

Java Collections & C++ Containers


Java Collections are symonymous with C++ Containers.

Java Collections Flowchart

C++ Containers Flowchart

Integer Types
C++ Type
Bits Min Max (on LLP64 or Java Type
LP64)

8 -2(8-1) = -128 2(8-1)-1 = 127 char byte

8 0 2(8)-1 = 255 unsigned char --

https://riptutorial.com/ 144
C++ Type
Bits Min Max (on LLP64 or Java Type
LP64)

16 -2(16-1) = -32,768 2(16-1)-1 = 32,767 short short

2(16)-1 = 65,535 char


16 0 (\u0000) unsigned short
(\uFFFF) (unsigned)

-2(32-1) = -2.147
32 2(32-1)-1 = 2.147 billion int int
billion

32 0 2(32)-1 = 4.295 billion unsigned int --

64 -2(64-1) 2(16-1)-1 long* long long

unsigned long*
64 0 2(16)-1 --
unsigned long long

* Win64 API is only 32 bit

Lots more C++ types

Examples
Static Class Members

Static members have class scope as opposed to object scope

C++ Example

// define in header
class Singleton {
public:
static Singleton *getInstance();

private:
Singleton() {}
static Singleton *instance;
};

// initialize in .cpp
Singleton* Singleton::instance = 0;

Java Example

public class Singleton {


private static Singleton instance;

https://riptutorial.com/ 145
private Singleton() {}

public static Singleton getInstance() {


if(instance == null) {
instance = new Singleton();
}
return instance;
}
}

Classes Defined within Other Constructs

Defined within Another Class


C++
Nested Class[ref] (needs a reference to enclosing class)

class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}

private:
Outer* outer;
};
};

Java
[non-static] Nested Class (aka Inner Class or Member Class)

class OuterClass {
...
class InnerClass {
...
}
}

Statically Defined within Another Class


C++
Static Nested Class

class Outer {
class Inner {
...

https://riptutorial.com/ 146
};
};

Java
Static Nested Class (aka Static Member Class)[ref]

class OuterClass {
...
static class StaticNestedClass {
...
}
}

Defined within a Method


(e.g. event handling)

C++
Local Class[ref]

void fun() {
class Test {
/* members of Test class */
};
}

Java
Local Class[ref]

class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}

Pass-by-value & Pass-by-reference

Many argue that Java is ONLY pass-by-value, but it's more nuanced than that. Compare the
following C++ and Java examples to see the many flavors of pass-by-value (aka copy) and pass-
by-reference (aka alias).

https://riptutorial.com/ 147
C++ Example (complete code)
// passes a COPY of the object
static void passByCopy(PassIt obj) {
obj.i = 22; // only a "local" change
}

// passes a pointer
static void passByPointer(PassIt* ptr) {
ptr->i = 33;
ptr = 0; // better to use nullptr instead if '0'
}

// passes an alias (aka reference)


static void passByAlias(PassIt& ref) {
ref.i = 44;
}

// This is an old-school way of doing it.


// Check out std::swap for the best way to do this
static void swap(PassIt** pptr1, PassIt** pptr2) {
PassIt* tmp = *pptr1;
*pptr1 = *pptr2;
*pptr2 = tmp;
}

Java Example (complete code)


// passes a copy of the variable
// NOTE: in java only primitives are pass-by-copy
public static void passByCopy(int copy) {
copy = 33; // only a "local" change
}

// No such thing as pointers in Java


/*
public static void passByPointer(PassIt *ptr) {
ptr->i = 33;
ptr = 0; // better to use nullptr instead if '0'
}
*/

// passes an alias (aka reference)


public static void passByAlias(PassIt ref) {
ref.i = 44;
}

// passes aliases (aka references),


// but need to do "manual", potentially expensive copies
public static void swap(PassIt ref1, PassIt ref2) {
PassIt tmp = new PassIt(ref1);
ref1.copy(ref2);
ref2.copy(tmp);
}

https://riptutorial.com/ 148
Inheritance vs Composition

C++ & Java are both object-oriented languages, thus the following diagram applies to both.

Outcast Downcasting

Beware of using "downcasting" - Downcasting is casting down the inheritance hierarchy from a
base class to a subclass (i.e. opposite of polymorphism). In general, use polymorphism &
overriding instead of instanceof & downcasting.

C++ Example
// explicit type case required
Child *pChild = (Child *) &parent;

Java Example
if(mySubClass instanceof SubClass) {
SubClass mySubClass = (SubClass)someBaseClass;
mySubClass.nonInheritedMethod();
}

Abstract Methods & Classes

Abstract Method
declared without an implementation

C++
pure virtual method

virtual void eat(void) = 0;

Java
abstract method

abstract void draw();

https://riptutorial.com/ 149
Abstract Class
cannot be instantiated

C++
cannot be instantiated; has at least 1 pure virtual method

class AB {public: virtual void f() = 0;};

Java
cannot be instantiated; can have non-abstract methods

abstract class GraphicObject {}

Interface
no instance fields

C++
nothing comparable to Java

Java
very similar to abstract class, but 1) supports multiple inheritance; 2) no instance fields

interface TestInterface {}

Read C++ Comparison online: https://riptutorial.com/java/topic/10849/cplusplus-comparison

https://riptutorial.com/ 150
Chapter 22: Calendar and its Subclasses
Remarks
As of Java 8, Calendar and its subclasses have been superseded by the java.time package and its
subpackages. They should be preferred, unless a legacy API requires Calendar.

Examples
Creating Calendar objects

Calendar objects can be created by using getInstance() or by using the constructor


GregorianCalendar.

It's important to notice that months in Calendar are zero based, which means that JANUARY is
represented by an int value 0. In order to provide a better code, always use Calendar constants,
such as Calendar.JANUARY to avoid misunderstandings.

Calendar calendar = Calendar.getInstance();


Calendar gregorianCalendar = new GregorianCalendar();
Calendar gregorianCalendarAtSpecificDay = new GregorianCalendar(2016, Calendar.JANUARY, 1);
Calendar gregorianCalendarAtSpecificDayAndTime = new GregorianCalendar(2016, Calendar.JANUARY,
1, 6, 55, 10);

Note: Always use the month constants: The numeric representation is misleading, e.g.
Calendar.JANUARY has the value 0

Increasing / Decreasing calendar fields

add() and roll() can be used to increase/decrease Calendar fields.

Calendar calendar = new GregorianCalendar(2016, Calendar.MARCH, 31); // 31 March 2016

The add() method affects all fields, and behaves effectively if one were to add or subtract actual
dates from the calendar

calendar.add(Calendar.MONTH, -6);

The above operation removes six months from the calendar, taking us back to 30 September
2015.

To change a particular field without affecting the other fields, use roll().

calendar.roll(Calendar.MONTH, -6);

The above operation removes six months from the current month, so the month is identified as

https://riptutorial.com/ 151
September. No other fields have been adjusted; the year has not changed with this operation.

Finding AM/PM

With Calendar class it is easy to find AM or PM.

Calendar cal = Calendar.getInstance();


cal.setTime(new Date());
if (cal.get(Calendar.AM_PM) == Calendar.PM)
System.out.println("It is PM");

Subtracting calendars

To get a difference between two Calendars, use getTimeInMillis() method:

Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c2.set(Calendar.DATE, c2.get(Calendar.DATE) + 1);

System.out.println(c2.getTimeInMillis() - c1.getTimeInMillis()); //outputs 86400000 (24 * 60 *


60 * 1000)

Read Calendar and its Subclasses online: https://riptutorial.com/java/topic/165/calendar-and-its-


subclasses

https://riptutorial.com/ 152
Chapter 23: Character encoding
Examples
Reading text from a file encoded in UTF-8

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

public class ReadingUTF8TextFile {

public static void main(String[] args) throws IOException {


//StandardCharsets is available since Java 1.7
//for ealier version use Charset.forName("UTF-8");
try (BufferedWriter wr = Files.newBufferedWriter(Paths.get("test.txt"),
StandardCharsets.UTF_8)) {
wr.write("Strange cyrillic symbol Ы");
}
/* First Way. For big files */
try (BufferedReader reader = Files.newBufferedReader(Paths.get("test.txt"),
StandardCharsets.UTF_8)) {

String line;
while ((line = reader.readLine()) != null) {
System.out.print(line);
}
}

System.out.println(); //just separating output

/* Second way. For small files */


String s = new String(Files.readAllBytes(Paths.get("test.txt")),
StandardCharsets.UTF_8);
System.out.print(s);
}
}

Writing text to a file in UTF-8

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

public class WritingUTF8TextFile {


public static void main(String[] args) throws IOException {
//StandardCharsets is available since Java 1.7
//for ealier version use Charset.forName("UTF-8");
try (BufferedWriter wr = Files.newBufferedWriter(Paths.get("test2.txt"),
StandardCharsets.UTF_8)) {

https://riptutorial.com/ 153
wr.write("Cyrillic symbol Ы");
}
}
}

Getting byte representation of a string in UTF-8

import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class GetUtf8BytesFromString {

public static void main(String[] args) {


String str = "Cyrillic symbol Ы";
//StandardCharsets is available since Java 1.7
//for ealier version use Charset.forName("UTF-8");
byte[] textInUtf8 = str.getBytes(StandardCharsets.UTF_8);

System.out.println(Arrays.toString(textInUtf8));
}
}

Read Character encoding online: https://riptutorial.com/java/topic/2735/character-encoding

https://riptutorial.com/ 154
Chapter 24: Choosing Collections
Introduction
Java offers a wide variety of Collections. Choosing which Collection to use can be tricky. See the
Examples section for an easy-to-follow flowchart to choose the right Collection for the job.

Examples
Java Collections Flowchart

Use the following flowchart to choose the right Collection for the job.

This flowchart was based off [http://i.stack.imgur.com/aSDsG.png).

Read Choosing Collections online: https://riptutorial.com/java/topic/10846/choosing-collections

https://riptutorial.com/ 155
Chapter 25: Class - Java Reflection
Introduction
The java.lang.Class class provides many methods that can be used to get metadata, examine and
change the run time behavior of a class.

The java.lang and java.lang.reflect packages provide classes for java reflection.

Where it is used

The Reflection API is mainly used in:

IDE (Integrated Development Environment) e.g. Eclipse, MyEclipse, NetBeans etc. Debugger Test
Tools etc.

Examples
getClass() method of Object class

class Simple { }

class Test {
void printName(Object obj){
Class c = obj.getClass();
System.out.println(c.getName());
}
public static void main(String args[]){
Simple s = new Simple();

Test t = new Test();


t.printName(s);
}
}

Read Class - Java Reflection online: https://riptutorial.com/java/topic/10151/class---java-reflection

https://riptutorial.com/ 156
Chapter 26: Classes and Objects
Introduction
Objects have states and behaviors. Example: A dog has states - color, name, breed as well as
behaviors – wagging the tail, barking, eating. An object is an instance of a class.

Class − A class can be defined as a template/blueprint that describes the behavior/state that the
object of its type support.

Syntax
• class Example {} //class keyword, name, body

Examples
Simplest Possible Class

class TrivialClass {}

A class consists at a minimum of the class keyword, a name, and a body, which might be empty.

You instantiate a class with the new operator.

TrivialClass tc = new TrivialClass();

Object Member vs Static Member

With this class:

class ObjectMemberVsStaticMember {

static int staticCounter = 0;


int memberCounter = 0;

void increment() {
staticCounter ++;
memberCounter++;
}
}

the following code snippet:

final ObjectMemberVsStaticMember o1 = new ObjectMemberVsStaticMember();


final ObjectMemberVsStaticMember o2 = new ObjectMemberVsStaticMember();

o1.increment();

https://riptutorial.com/ 157
o2.increment();
o2.increment();

System.out.println("o1 static counter " + o1.staticCounter);


System.out.println("o1 member counter " + o1.memberCounter);
System.out.println();

System.out.println("o2 static counter " + o2.staticCounter);


System.out.println("o2 member counter " + o2.memberCounter);
System.out.println();

System.out.println("ObjectMemberVsStaticMember.staticCounter = " +
ObjectMemberVsStaticMember.staticCounter);

// the following line does not compile. You need an object


// to access its members
//System.out.println("ObjectMemberVsStaticMember.staticCounter = " +
ObjectMemberVsStaticMember.memberCounter);

produces this output:

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.

Overloading Methods

Sometimes the same functionality has to be written for different kinds of inputs. At that time, one
can use the same method name with a different set of parameters. Each different set of
parameters is known as a method signature. As seen per the example, a single method can have
multiple signatures.

public class Displayer {

public void displayName(String firstName) {


System.out.println("Name is: " + firstName);
}

public void displayName(String firstName, String lastName) {


System.out.println("Name is: " + firstName + " " + lastName);
}

public static void main(String[] args) {

https://riptutorial.com/ 158
Displayer displayer = new Displayer();
displayer.displayName("Ram"); //prints "Name is: Ram"
displayer.displayName("Jon", "Skeet"); //prints "Name is: Jon Skeet"
}
}

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.

Methods can be overloaded:

1. Based on the number of parameters passed.

Example: method(String s) and method(String s1, String s2).

2. Based on the order of parameters.

Example: method(int i, float f) and method(float f, int i)).

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.

Basic Object Construction and Use

Objects come in their own class, so a simple example would be a car (detailed explanations
below):

public class Car {

//Variables describing the characteristics of an individual car, varies per object


private int milesPerGallon;
private String name;
private String color;
public int numGallonsInTank;

public Car(){
milesPerGallon = 0;
name = "";
color = "";
numGallonsInTank = 0;
}

//this is where an individual object is created


public Car(int mpg, int, gallonsInTank, String carName, String carColor){
milesPerGallon = mpg;
name = carName;
color = carColor;
numGallonsInTank = gallonsInTank;
}

//methods to make the object more usable

//Cars need to drive

https://riptutorial.com/ 159
public void drive(int distanceInMiles){
//get miles left in car
int miles = numGallonsInTank * milesPerGallon;

//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!");
}
}

public void paintCar(String newColor){


color = newColor;
}
//set new Miles Per Gallon
public void setMPG(int newMPG){
milesPerGallon = newMPG;
}

//set new number of Gallon In Tank


public void setGallonsInTank(int numGallons){
numGallonsInTank = numGallons;
}

public void nameCar(String newName){


name = newName;
}

//Get the Car color


public String getColor(){
return color;
}

//Get the Car name


public String getName(){
return name;
}

//Get the number of Gallons


public String getGallons(){
return numGallonsInTank;
}

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

`Car newCar = new Car(30, 10, "Ferrari", "Red");

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:

https://riptutorial.com/ 160
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:

String myCarName = newCar.getName(); //returns string "Ferrari"

Option 1 is the best option when you have all the object's data at the time of creation.

Option 2

`Car newCar = new Car();

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:

public void Car(){


milesPerGallon = 0;
name = "";
color = "";
numGallonsInTank = 0;
}

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 are thrown.

Note: Do not forget that you have to set the parts of the object later that you did not initialize it
with. For example,

Car myCar = new Car();


String color = Car.getColor(); //returns empty string

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:

Car myCar = new Car();


myCar.nameCar("Ferrari");
myCar.paintCar("Purple");
myCar.setGallonsInTank(10);
myCar.setMPG(30);

https://riptutorial.com/ 161
And, as a reminder, get an object's properties by calling a method in your main class. Example:

String myCarName = myCar.getName(); //returns string "Ferrari"

Constructors

Constructors are special methods named after the class and without a return type, and are used to
construct objects. Constructors, like methods, can take input parameters. Constructors are used to
initialize objects. Abstract classes can have constructors also.

public class Hello{


// constructor
public Hello(String wordToPrint){
printHello(wordToPrint);
}
public void printHello(String word){
System.out.println(word);
}
}
// instantiates the object during creating and prints out the content
// of wordToPrint

It is important to understand that constructors are different from methods in several ways:

1. Constructors can only take the modifiers public, private, and protected, and cannot be
declared abstract, final, static, or synchronized.

2. Constructors do not have a return type.

3. 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.

4. 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 class SuperManClass{

public SuperManClass(){
// some implementation
}

// ... methods
}

public class BatmanClass extends SupermanClass{


public BatmanClass(){
super();
}
//... methods...

https://riptutorial.com/ 162
}

See Java Language Specification #8.8 and #15.9

Initializing static final fields using a static initializer

To initialize a static final fields that require using more than a single expression, a static
initializer can be used to assign the value. The following example initializes a unmodifiable set of
Strings:

public class MyClass {

public static final Set<String> WORDS;

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);
}
}

Explaining what is method overloading and overriding.

Method Overriding and Overloading are two forms of polymorphism supported by Java.

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.

public class Shape{


//It could be a circle or rectangle or square
private String type;

//To calculate area of rectangle


public Double area(Long length, Long breadth){
return (Double) length * breadth;
}

//To calculate area of a circle


public Double area(Long radius){
return (Double) 3.14 * r * r;
}
}

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?

https://riptutorial.com/ 163
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

May have different return types.

May have different access modifiers.

May throw different exceptions.

Why is this called static polymorphism?

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.

One of common reasons of using method overloading is the simplicity of code it


provides. For example remember String.valueOf() which takes almost any type of
argument? What is written behind the scene is probably something like this :-

static String valueOf(boolean b)


static String valueOf(char c)
static String valueOf(char[] data)
static String valueOf(char[] data, int offset, int count)
static String valueOf(double d)
static String valueOf(float f)
static String valueOf(int i)
static String valueOf(long l)
static String valueOf(Object obj)

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.

public abstract class Shape{

public abstract Double area(){


return 0.0;
}
}

So we have a class called Shape and it has method called area which will probably return the area

https://riptutorial.com/ 164
of the shape.

Let's say now we have two classes called Circle and Rectangle.

public class Circle extends Shape {


private Double radius = 5.0;

// 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;
}
}

Similarly rectangle class:

public class Rectangle extends Shape {


private Double length = 5.0;
private Double breadth= 10.0;

// 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.

public class AreaFinder{

public static void main(String[] args){

//This will create an object of circle class


Shape circle = new Circle();
//This will create an object of Rectangle class
Shape rectangle = new Rectangle();

// Drumbeats ......
//This should print 78.5
System.out.println("Shape of circle : "+circle.area());

//This should print 50.0


System.out.println("Shape of rectangle: "+rectangle.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.

Here's a chart to better compare the differences between these two:-

https://riptutorial.com/ 165
Method Overloading Method Overriding

Method overriding is used to provide


Method overloading is used to increase the the specific implementation of the
readability of the program. method that is already provided by its
super class.

Method overriding occurs in two


Method overloading is performed within class. classes that have IS-A (inheritance)
relationship.

In case of method overloading, parameter must be In case of method overriding,


different. parameter must be same.

Method overloading is the example of compile time Method overriding is the example of
polymorphism. run time polymorphism.

In java, method overloading can't be performed by


changing return type of the method only. Return type Return type must be same or
can be same or different in method overloading. But covariant in method overriding.
you must have to change the parameter.

Read Classes and Objects online: https://riptutorial.com/java/topic/114/classes-and-objects

https://riptutorial.com/ 166
Chapter 27: Classloaders
Remarks
A classloader is a class whose primary purpose is to mediate the location and loading of classes
used by an application. A class loader can also find and loaded resources.

The standard classloader classes can load classes and resources from directories in the file
system and from JAR and ZIP files. They can also download and cache JAR and ZIP files from a
remote server.

Classloaders are normally chained, so that the JVM will try to load classes from the standard class
libraries in preference to application-provided sources. Custom classloaders allow the programmer
to alter this. The also can do such things as decrypting bytecode files and bytecode modification.

Examples
Instantiating and using a classloader

This basic example shows how an application can instantiate a classloader and use it to
dynamically load a class.

URL[] urls = new URL[] {new URL("file:/home/me/extras.jar")};


Classloader loader = new URLClassLoader(urls);
Class<?> myObjectClass = loader.findClass("com.example.MyObject");

The classloader created in this example will have the default classloader as its parent, and will first
try to find any class in the parent classloader before looking in "extra.jar". If the requested class
has already been loaded, the findClass call will return the reference to the previously loaded class.

The findClass call can fail in a variety of ways. The most common are:

• If the named class cannot be found, the call with throw ClassNotFoundException.
• If the named class depends on some other class that cannot be found, the call will throw
NoClassDefFoundError.

Implementing a custom classLoader

Every custom loader must directly or indirectly extend the java.lang.ClassLoader class. The main
extension points are the following methods:

• - overload this method if your classloader follows the standard delegation


findClass(String)
model for class loading.
• loadClass(String, boolean) - overload this method to implement an alternative delegation
model.
• findResource and findResources - overload these methods to customize resource loading.

https://riptutorial.com/ 167
The defineClass methods which are responsible for actually loading the class from a byte array are
final to prevent overloading. Any custom behavior needs to be performed prior to calling
defineClass.

Here is a simple that loads a specific class from a byte array:

public class ByteArrayClassLoader extends ClassLoader {


private String classname;
private byte[] classfile;

public ByteArrayClassLoader(String classname, byte[] classfile) {


this.classname = classname;
this.classfile = classfile.clone();
}

@Override
protected Class findClass(String classname) throws ClassNotFoundException {
if (classname.equals(this.classname)) {
return defineClass(classname, classfile, 0, classfile.length);
} else {
throw new ClassNotFoundException(classname);
}
}
}

Since we have only overridden the findClass method, this custom class loader is going to behave
as follows when loadClass is called.

1. The classloader's loadClass method calls findLoadedClass to see if a class with this name has
already been loaded by this classloader. If that succeeds, the resulting Class object is
returned to the requestor.
2. The loadClass method then delegates to the parent classloader by calling its loadClass call. If
the parent can deal with the request, it will return a Class object which is then returned to the
requestor.
3. If the parent classloader cannot load the class, findClass then calls our override findClass
method, passing the name of the class to be loaded.
4. If the requested name matches this.classname, we call defineClass to load the actual class
from the this.classfile byte array. The resulting Class object is then returned.
5. If the name did not match, we throw ClassNotFoundException.

Loading an external .class file

To load a class we first need to define it. The class is defined by the ClassLoader. There's just one
problem, Oracle didn't write the ClassLoader's code with this feature available. To define the class
we will need to access a method named defineClass() which is a private method of the ClassLoader
.

To access it, what we will do is create a new class, ByteClassLoader, and extend it to ClassLoader.
Now that we have extended our class to ClassLoader, we can access the ClassLoader's private
methods. To make defineClass() available, we will create a new method that will act like a mirror
for the private defineClass() method. To call the private method we will need the class name, name,

https://riptutorial.com/ 168
the class bytes, classBytes, the first byte's offset, which will be 0 because classBytes' data starts at
classBytes[0], and the last byte's offset, which will be classBytes.lenght because it represents the
size of the data, which will be the last offset.

public class ByteClassLoader extends ClassLoader {

public Class<?> defineClass(String name, byte[] classBytes) {


return defineClass(name, classBytes, 0, classBytes.length);
}

Now, we have a public defineClass() method. It can be called by passing the name of the class
and the class bytes as arguments.

Let's say we have class named MyClass in the package stackoverflow...

To call the method we need the class bytes so we create a Path object representing our class' path
by using the Paths.get() method and passing the path of the binary class as an argument. Now,
we can get the class bytes with Files.readAllBytes(path). So we create a ByteClassLoader instance
and use the method we created, defineClass(). We already have the class bytes but to call our
method we also need the class name which is given by the package name (dot) the class
canonical name, in this case stackoverflow.MyClass.

Path path = Paths.get("MyClass.class");

ByteClassLoader loader = new ByteClassLoader();


loader.defineClass("stackoverflow.MyClass", Files.readAllBytes(path);

Note: The defineClass() method returns a Class<?> object. You can save it if you want.

To load the class, we just call loadClass() and pass the class name. This method can throw an
ClassNotFoundException so we need to use a try cath block

try{
loader.loadClass("stackoverflow.MyClass");
} catch(ClassNotFoundException e){
e.printStackTrace();
}

Read Classloaders online: https://riptutorial.com/java/topic/5443/classloaders

https://riptutorial.com/ 169
Chapter 28: Collection Factory Methods
Introduction
The arrival of Java 9 brings many new features to Java's Collections API, one of which being
collection factory methods. These methods allow for easy initialization of immutable collections,
whether they be empty or nonempty.

Note that these factory methods are only available for the following interfaces: List<E>, Set<E>, and
Map<K, V>

Syntax
• static <E> List<E> of()
• static <E> List<E> of(E e1)
• static <E> List<E> of(E e1, E e2)
• static <E> List<E> of(E e1, E e2, ..., E e9, E e10)
• static <E> List<E> of(E... elements)
• static <E> Set<E> of()
• static <E> Set<E> of(E e1)
• static <E> Set<E> of(E e1, E e2)
• static <E> Set<E> of(E e1, E e2, ..., E e9, E e10)
• static <E> Set<E> of(E... elements)
• static <K,V> Map<K,V> of()
• static <K,V> Map<K,V> of(K k1, V v1)
• static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2)
• static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, ..., K k9, V v9, K k10, V v10)
• static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)

Parameters

Method w/ Parameter Description

List.of(E e) A generic type that can be a class or interface.

Set.of(E e) A generic type that can be a class or interface.

A key-value pair of generic types that can each be a class


Map.of(K k, V v)
or interface.

Map.of(Map.Entry<? extends K, ? A Map.Entry instance where its key can be K or one of its
extends V> entry) children, and its value can be V or any of its children.

Examples
List Factory Method Examples

https://riptutorial.com/ 170
• List<Integer> immutableEmptyList = List.of();
○ Initializes an empty, immutable List<Integer>.
• List<Integer> immutableList = List.of(1, 2, 3, 4, 5);
○ Initializes an immutable List<Integer> with five initial elements.
• List<Integer> mutableList = new ArrayList<>(immutableList);
○ Initializes a mutable List<Integer> from an immutable List<Integer>.

Set Factory Method Examples


• Set<Integer> immutableEmptySet = Set.of();
○ Initializes an empty, immutable Set<Integer>.
• Set<Integer> immutableSet = Set.of(1, 2, 3, 4, 5);
○ Initializes an immutable Set<Integer> with five initial elements.
• Set<Integer> mutableSet = new HashSet<>(immutableSet);
○ Initializes a mutable Set<Integer> from an immutable Set<Integer>.

Map Factory Method Examples


• Map<Integer, Integer> immutableEmptyMap = Map.of();
○ Initializes an empty, immutable Map<Integer, Integer>.
• Map<Integer, Integer> immutableMap = Map.of(1, 2, 3, 4);
○ Initializes an immutable Map<Integer, Integer> with two initial key-value entries.
• Map<Integer, Integer> immutableMap = Map.ofEntries(Map.entry(1, 2), Map.entry(3, 4));
○ Initializes an immutable Map<Integer, Integer> with two initial key-value entries.
• Map<Integer, Integer> mutableMap = new HashMap<>(immutableMap);
○ Initializes a mutable Map<Integer, Integer> from an immutable Map<Integer, Integer>.

Read Collection Factory Methods online: https://riptutorial.com/java/topic/9783/collection-factory-


methods

https://riptutorial.com/ 171
Chapter 29: Collections
Introduction
The collections framework in java.util provides a number of generic classes for sets of data with
functionality that can't be provided by regular arrays.

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.

Remarks
Collections are objects that can store collections of other objects inside of them. You can specify
the type of data stored in a collection using Generics.

Collections generally use the java.util or java.util.concurrent namespaces.

Java SE 1.4

Java 1.4.2 and below do not support generics. As such, you can not specify the type parameters
that a collection contains. In addition to not having type safety, you must also use casts to get the
correct type back from a collection.

In addition to Collection<E>, there are multiple major types of collections, some of which have
subtypes.

• List<E> is an ordered collection of objects. It is similar to an array, but does not define a size
limit. Implementations will usually grow in size internally to accomodate new elements.
• Set<E> is a collection of objects that does not allow duplicates.
○ SortedSet<E> is a Set<E> that also specifies element ordering.
• Map<K,V> is a collection of key/value pairs.
○ SortedMap<K,V> is a Map<K,V> that also specifies element ordering.

Java SE 5

Java 5 adds in a new collection type:

• is a collection of elements meant to be processed in a specific order. The


Queue<E>
implementation specifies whether this is FIFO or LIFO. This obsoletes the Stack class.

Java SE 6

Java 6 adds in some new subtypes of collections.

• NavigableSet<E> is a Set<E> with special navigation methods built in.


• NavigableMap<K,V> is a Map<K,V> with special navigation methods built in.

https://riptutorial.com/ 172
• Deque<E> is a Queue<E> that can be read from either end.

Note that the above items are all interfaces. In order to use them, you must find the appropriate
implementing classes, such as ArrayList, HashSet, HashMap, or PriorityQueue.

Each type of collection has multiple implementations that have different performance metrics and
use cases.

Note that the Liskov Substitution Principle applies to the collection subtypes. That is, a
SortedSet<E> can be passed to a function expecting a Set<E>. It is also useful to read about
Bounded Parameters in the Generics section for more information on how to use collections with
class inheritance.

If you want to create your own collections, it may be easier to inherit one of the abstract classes
(such as AbstractList) instead of implementing the interface.

Java SE 1.2

Prior to 1.2, you had to use the following classes/interfaces instead:

• instead of ArrayList
Vector
• Dictionary instead of Map. Note that Dictionary is also an abstract class rather than an
interface.
• Hashtable instead of HashMap

These classes are obsolete and should not be used in modern code.

Examples
Declaring an ArrayList and adding objects

We can create an ArrayList (following the List interface):

List aListOfFruits = new ArrayList();

Java SE 5

List<String> aListOfFruits = new ArrayList<String>();

Java SE 7

List<String> aListOfFruits = new ArrayList<>();

Now, use the method add to add a String:

aListOfFruits.add("Melon");
aListOfFruits.add("Strawberry");

In the above example, the ArrayList will contain the String "Melon" at index 0 and the String

https://riptutorial.com/ 173
"Strawberry" at index 1.

Also we can add multiple elements with addAll(Collection<? extends E> c) method

List<String> aListOfFruitsAndVeggies = new ArrayList<String>();


aListOfFruitsAndVeggies.add("Onion");
aListOfFruitsAndVeggies.addAll(aListOfFruits);

Now "Onion" is placed at 0 index in aListOfFruitsAndVeggies, "Melon" is at index 1 and "Strawberry"


is at index 2.

Constructing collections from existing data

Standard Collections
Java Collections framework
A simple way to construct a List from individual data values is to use java.utils.Arrays method
Arrays.asList:

List<String> data = Arrays.asList("ab", "bc", "cd", "ab", "bc", "cd");

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:

List<String> list = new ArrayList<>(data); // will add data as is


Set<String> set1 = new HashSet<>(data); // will add data keeping only unique values
SortedSet<String> set2 = new TreeSet<>(data); // will add data keeping unique values and
sorting
Set<String> set3 = new LinkedHashSet<>(data); // will add data keeping only unique values and
preserving the original order

Google Guava Collections framework


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

https://riptutorial.com/ 174
Java Collections framework
Similarly for maps, given a Map<String, Object> map a new map can be constructed with all
elements as follows:

Map<String, Object> map1 = new HashMap<>(map);


SortedMap<String, Object> map2 = new TreeMap<>(map);

Apache Commons Collections framework


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

// Create a Map mapping colors.


Map colorMap = MapUtils.toMap(new String[][] {{
{"RED", "#FF0000"},
{"GREEN", "#00FF00"},
{"BLUE", "#0000FF"}});

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.

Google Guava Collections framework


Utility class from Google Guava framework is named Maps:

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
}

Java SE 8

Using Stream,

Stream.of("xyz", "abc").collect(Collectors.toList());

or

Arrays.stream("xyz", "abc").collect(Collectors.toList());

https://riptutorial.com/ 175
Join lists

Following ways can be used for joining lists without modifying source list(s).

First approach. Has more lines but easy to understand

List<String> newList = new ArrayList<String>();


newList.addAll(listOne);
newList.addAll(listTwo);

Second approach. Has one less line but less readable.

List<String> newList = new ArrayList<String>(listOne);


newList.addAll(listTwo);

Third approach. Requires third party Apache commons-collections library.

ListUtils.union(listOne,listTwo);

Java SE 8

Using Streams the same can be achieved by

List<String> newList = Stream.concat(listOne.stream(),


listTwo.stream()).collect(Collectors.toList());

References. Interface List

Removing items from a List within a loop

It is tricky to remove items from a list while within a loop, this is due to the fact that the index and
length of the list gets changed.

Given the following list, here are some examples that will give an unexpected result and some that
will give the correct result.

List<String> fruits = new ArrayList<String>();


fruits.add("Apple");
fruits.add("Banana");
fruits.add("Strawberry");

INCORRECT
Removing in iteration of for statement Skips "Banana":
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.

https://riptutorial.com/ 176
for (int i = 0; i < fruits.size(); i++) {
System.out.println (fruits.get(i));
if ("Apple".equals(fruits.get(i))) {
fruits.remove(i);
}
}

Removing in the enhanced for statement Throws Exception:


Because of iterating over collection and modifying it at the same time.

Throws: java.util.ConcurrentModificationException

for (String fruit : fruits) {


System.out.println(fruit);
if ("Apple".equals(fruit)) {
fruits.remove(fruit);
}
}

CORRECT
Removing in while loop using an Iterator

Iterator<String> fruitIterator = fruits.iterator();


while(fruitIterator.hasNext()) {
String fruit = fruitIterator.next();
System.out.println(fruit);
if ("Apple".equals(fruit)) {
fruitIterator.remove();
}
}

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.

Throws: UnsupportedOperationException - if the remove operation is not supported by


this iterator

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

https://riptutorial.com/ 177
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:

Iterator<String> fruitIterator = fruits.iterator();


fruits.set(0, "Watermelon");
while(fruitIterator.hasNext()){
System.out.println(fruitIterator.next());
}

But adding a new element to the List after initializing an Iterator will throw a
ConcurrentModificationException:

Iterator<String> fruitIterator = fruits.iterator();


fruits.add("Watermelon");
while(fruitIterator.hasNext()){
System.out.println(fruitIterator.next()); //ConcurrentModificationException here
}

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.

Iterating forward, adjusting the loop index

for (int i = 0; i < fruits.size(); i++) {


System.out.println (fruits.get(i));
if ("Apple".equals(fruits.get(i))) {
fruits.remove(i);
i--;
}
}

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.

https://riptutorial.com/ 178
Using a "should-be-removed" list

ArrayList shouldBeRemoved = new ArrayList();


for (String str : currentArrayList) {
if (condition) {
shouldBeRemoved.add(str);
}
}
currentArrayList.removeAll(shouldBeRemoved);

This solution enables the developer to check if the correct elements are removed in a cleaner way.

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.

fruits.removeIf(p -> "Apple".equals(p));

Unmodifiable Collection

Sometimes it's not a good practice expose an internal collection since it can lead to a malicious
code vulnerability due to it's mutable characteristic. In order to provide "read-only" collections java
provides its unmodifiable versions.

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;

https://riptutorial.com/ 179
public class MyPojoClass {
private List<Integer> intList = new ArrayList<>();

public void addValueToIntList(Integer value){


intList.add(value);
}

public List<Integer> getIntList() {


return Collections.unmodifiableList(intList);
}
}

The following attempt to modify an unmodifiable collection will throw an exception:

import java.util.List;

public class App {

public static void main(String[] args) {


MyPojoClass pojo = new MyPojoClass();
pojo.addValueToIntList(42);

List<Integer> list = pojo.getIntList();


list.add(69);
}
}

output:

Exception in thread "main" java.lang.UnsupportedOperationException


at java.util.Collections$UnmodifiableCollection.add(Collections.java:1055)
at App.main(App.java:12)

Iterating over Collections

Iterating over List


List<String> names = new ArrayList<>(Arrays.asList("Clementine", "Duran", "Mike"));

Java SE 8

names.forEach(System.out::println);

If we need parallelism use

names.parallelStream().forEach(System.out::println);

Java SE 5

for (String name : names) {

https://riptutorial.com/ 180
System.out.println(name);
}

Java SE 5

for (int i = 0; i < names.size(); i++) {


System.out.println(names.get(i));
}

Java SE 1.2

//Creates ListIterator which supports both forward as well as backward traversel


ListIterator<String> listIterator = names.listIterator();

//Iterates list in forward direction


while(listIterator.hasNext()){
System.out.println(listIterator.next());
}

//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"));

Java SE 8

names.forEach(System.out::println);

Java SE 5

for (Iterator<String> iterator = names.iterator(); iterator.hasNext(); ) {


System.out.println(iterator.next());
}

for (String name : names) {


System.out.println(name);
}

Java SE 5

Iterator iterator = names.iterator();


while (iterator.hasNext()) {
System.out.println(iterator.next());
}

Iterating over Map


https://riptutorial.com/ 181
Map<Integer, String> names = new HashMap<>();
names.put(1, "Clementine");
names.put(2, "Duran");
names.put(3, "Mike");

Java SE 8

names.forEach((key, value) -> System.out.println("Key: " + key + " Value: " + value));

Java SE 5

for (Map.Entry<Integer, String> entry : names.entrySet()) {


System.out.println(entry.getKey());
System.out.println(entry.getValue());
}

// Iterating over only keys


for (Integer key : names.keySet()) {
System.out.println(key);
}
// Iterating over only values
for (String value : names.values()) {
System.out.println(value);
}

Java SE 5

Iterator entries = names.entrySet().iterator();


while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}

Immutable Empty Collections

Sometimes it is appropriate to use an immutable empty collection. The Collections class provides
methods to get such collections in an efficient way:

List<String> anEmptyList = Collections.emptyList();


Map<Integer, Date> anEmptyMap = Collections.emptyMap();
Set<Number> anEmptySet = Collections.emptySet();

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.

Collections and Primitive Values

https://riptutorial.com/ 182
Collections in Java only work for objects. I.e. there is no Map<int, int> in Java. Instead, primitive
values need to be boxed into objects, as in Map<Integer, Integer>. Java auto-boxing will enable
transparent use of these collections:

Map<Integer, Integer> map = new HashMap<>();


map.put(1, 17); // Automatic boxing of int to Integer objects
int a = map.get(1); // Automatic unboxing.

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.

Removing matching items from Lists using Iterator.

Above I noticed an example to remove items from a List within a Loop and I thought of another
example that may come in handy this time using the Iterator interface.
This is a demonstration of a trick that might come in handy when dealing with duplicate items in
lists that you want to get rid of.

Note: This is only adding on to the Removing items from a List within a loop example:

So let's define our lists as usual

String[] names = {"James","Smith","Sonny","Huckle","Berry","Finn","Allan"};


List<String> nameList = new ArrayList<>();

//Create a List from an Array


nameList.addAll(Arrays.asList(names));

String[] removeNames = {"Sonny","Huckle","Berry"};


List<String> removeNameList = new ArrayList<>();

//Create a List from an Array


removeNameList.addAll(Arrays.asList(removeNames));

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.

private static void removeNames(Collection<String> collection1, Collection<String>


collection2) {
//get Iterator.
Iterator<String> iterator = collection1.iterator();

//Loop while collection has items


while(iterator.hasNext()){
if (collection2.contains(iterator.next()))

https://riptutorial.com/ 183
iterator.remove(); //remove the current Name or Item
}
}

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.

Creating your own Iterable structure for use with Iterator or for-each loop.

To ensure that our collection can be iterated using iterator or for-each loop, we have to take care
of following steps:

1. The stuff we want to iterate upon has to be Iterable and expose iterator().
2. Design a java.util.Iterator by overriding hasNext(), next() and remove().

I have added a simple generic linked list implementation below that uses above entities to make
the linked list iterable.

package org.algorithms.linkedlist;
 
import java.util.Iterator;
import java.util.NoSuchElementException;
 
 
public class LinkedList<T> implements Iterable<T> {
 
    Node<T> head, current;
 
    private static class Node<T> {
        T data;
        Node<T> next;
 
        Node(T data) {
            this.data = data;
        }
    }
 
    public LinkedList(T data) {
        head = new Node<>(data);
    }
 
    public Iterator<T> iterator() {
        return new LinkedListIterator();
    }
 
    private class LinkedListIterator implements Iterator<T> {
 
        Node<T> node = head;

https://riptutorial.com/ 184
 
        @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.");
        }
    }
 
    public void add(T data) {
        Node current = head;
        while (current.next != null)
            current = current.next;
        current.next = new Node<>(data);
    }
 
}
 
class App {
    public static void main(String[] args) {
 
        LinkedList<Integer> list = new LinkedList<>(1);
        list.add(2);
        list.add(4);
        list.add(3);
 
        //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

https://riptutorial.com/ 185
This will run in Java 7+. You can make it run on Java 5 and Java 6 also by substituting:

LinkedList<Integer> list = new LinkedList<>(1);

with

LinkedList<Integer> list = new LinkedList<Integer>(1);

or just any other version by incorporating the compatible changes.

Pitfall: concurrent modification exceptions

This exception occurs when a collection is modified while iterating over it using methods other
than those provided by the iterator object. For example, we have a list of hats and we want to
remove all those that have ear flaps:

List<IHat> hats = new ArrayList<>();


hats.add(new Ushanka()); // that one has ear flaps
hats.add(new Fedora());
hats.add(new Sombrero());
for (IHat hat : hats) {
if (hat.hasEarFlaps()) {
hats.remove(hat);
}
}

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.

Sub Collections

List subList(int fromIndex, int toIndex)


Here fromIndex is inclusive and toIndex is exclusive.

List list = new ArrayList();


List list1 = list.subList(fromIndex,toIndex);

1. If the list doesn't exist in the give range, it throws IndexOutofBoundException.


2. What ever changes made on the list1 will impact the same changes in the list.This is called
backed collections.
3. If the fromnIndex is greater than the toIndex (fromIndex > toIndex) it throws
IllegalArgumentException.

https://riptutorial.com/ 186
Example:

List<String> list = new ArrayList<String>();


List<String> list = new ArrayList<String>();
list.add("Hello1");
list.add("Hello2");
System.out.println("Before Sublist "+list);
List<String> list2 = list.subList(0, 1);
list2.add("Hello3");
System.out.println("After sublist changes "+list);

Output:
Before Sublist [Hello1, Hello2]
After sublist changes [Hello1, Hello3, Hello2]

Set subSet(fromIndex,toIndex)
Here fromIndex is inclusive and toIndex is exclusive.

Set set = new TreeSet();


Set set1 = 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)
fromKey is inclusive and toKey is exclusive

Map map = new TreeMap();


Map map1 = map.get(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.

Read Collections online: https://riptutorial.com/java/topic/90/collections

https://riptutorial.com/ 187
Chapter 30: Command line Argument
Processing
Syntax
• public static void main(String[] args)

Parameters

Parameter Details

The command line arguments. Assuming that the main method is invoked by the
args
Java launcher, args will be non-null, and will have no null elements.

Remarks
When a regular Java application is launched using the java command (or equivalent), a main
method will be called, passing the arguments from the command line in the args array.

Unfortunately, the Java SE class libraries do not provide any direct support for command
argument processing. This leaves you two alternatives:

• Implement the argument processing by hand in Java.


• Make use of a 3rd-party library.

This Topic will attempt to cover some of the more popular 3rd-party libraries. For an extensive list
of the alternatives, see this answer to the StackOverflow Question "How to parse command line
arguments in Java?".

Examples
Argument processing using GWT ToolBase

If you want to parse more complex command-line arguments, e.g. with optional parameters, than
the best is to use google's GWT approach. All classes are public available at:

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 class MyProgramHandler extends ToolBase {


protected File dir;

https://riptutorial.com/ 188
protected int port;
// getters for dir and port
...

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)) {
// main program operation
System.out.println(String.format("port: %d; dir: %s",
myShell.getPort(), myShell.getDir()));
}
System.exit(1);
}
}

ArgHandleralso 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.

Processing arguments by hand

When the command-line syntax for an application is simple, it is reasonable to do the command
argument processing entirely in custom code.

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".)

A command with no arguments


In this case-study, the command requires no arguments. The code illustrates that args.length
gives us the number of command line arguments.

public class Main {


public static void main(String[] args) {
if (args.length > 0) {
System.err.println("usage: myapp");

https://riptutorial.com/ 189
System.exit(1);
}
// Run the application
System.out.println("It worked");
}
}

A command with two arguments


In this case-study, the command requires at precisely two arguments.

public class Main {


public static void main(String[] args) {
if (args.length != 2) {
System.err.println("usage: myapp <arg1> <arg2>");
System.exit(1);
}
// Run the application
System.out.println("It worked: " + args[0] + ", " + args[1]);
}
}

Note that if we neglected to check args.length, the command would crash if the user ran it with too
few command-line arguments.

A command with "flag" options and at least one argument


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":
feelMe = true;
break;
default:
if (!opts.isEmpty() && opts.charAt(0) == '-') {
error("Unknown option: '" + opt + "');
}
break loop;
}
}
if (index >= args.length) {
error("Missing argument(s)");
}

https://riptutorial.com/ 190
// Run the application
// ...
}

private static void error(String message) {


if (message != null) {
System.err.println(message);
}
System.err.println("usage: myapp [-f] [-c] [ <arg> ...]");
System.exit(1);
}
}

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.

Read Command line Argument Processing online:


https://riptutorial.com/java/topic/4775/command-line-argument-processing

https://riptutorial.com/ 191
Chapter 31: Common Java Pitfalls
Introduction
This topic outlines some of the common mistakes made by beginners in Java.

This includes any common mistakes in use of the Java language or understanding of the run-time
environment.

Mistakes associated with specific APIs can be described in topics specific to those APIs. Strings
are a special case; they're covered in the Java Language Specification. Details other than
common mistakes can be described in this topic on Strings.

Examples
Pitfall: using == to compare primitive wrappers objects such as Integer

(This pitfall applies equally to all primitive wrapper types, but we will illustrate it for Integer and int
.)

When working with Integer objects, it is tempting to use == to compare values, because that is
what you would do with int values. And in some cases this will seem to work:

Integer int1_1 = Integer.valueOf("1");


Integer int1_2 = Integer.valueOf(1);

System.out.println("int1_1 == int1_2: " + (int1_1 == int1_2)); // true


System.out.println("int1_1 equals int1_2: " + int1_1.equals(int1_2)); // true

Here we created two Integer objects with the value 1 and compare them (In this case we created
one from a String and one from an int literal. There are other alternatives). Also, we observe that
the two comparison methods (== and equals) both yield true.

This behavior changes when we choose different values:

Integer int2_1 = Integer.valueOf("1000");


Integer int2_2 = Integer.valueOf(1000);

System.out.println("int2_1 == int2_2: " + (int2_1 == int2_2)); // false


System.out.println("int2_1 equals int2_2: " + int2_1.equals(int2_2)); // true

In this case, only the equals comparison yields the correct result.

The reason for this difference in behavior is, that the JVM maintains a cache of Integer objects for
the range -128 to 127. (The upper value can be overridden with the system property
"java.lang.Integer.IntegerCache.high" or the JVM argument "-XX:AutoBoxCacheMax=size"). For
values in this range, the Integer.valueOf() will return the cached value rather than creating a new

https://riptutorial.com/ 192
one.

Thus, in the first example the Integer.valueOf(1) and Integer.valueOf("1") calls returned the same
cached Integer instance. By contrast, in the second example the Integer.valueOf(1000) and
Integer.valueOf("1000") both created and returned new Integer objects.

The == operator for reference types tests for reference equality (i.e. the same object). Therefore, in
the first example int1_1 == int1_2 is true because the references are the same. In the second
example int2_1 == int2_2 is false because the references are different.

Pitfall: forgetting to free resources

Every time a program opens a resource, such as a file or network connection, it is important to
free the resource once you are done using it. Similar caution should be taken if any exception
were to be thrown during operations on such resources. One could argue that the FileInputStream
has a finalizer that invokes the close() method on a garbage collection event; however, since we
can’t be sure when a garbage collection cycle will start, the input stream can consume computer
resources for an indefinite period of time. The resource must be closed in a finally section of a
try-catch block:

Java SE 7

private static void printFileJava6() throws IOException {


FileInputStream input;
try {
input = new FileInputStream("file.txt");
int data = input.read();
while (data != -1){
System.out.print((char) data);
data = input.read();
}
} finally {
if (input != null) {
input.close();
}
}
}

Since Java 7 there is a really useful and neat statement introduced in Java 7 particularly for this
case, called try-with-resources:

Java SE 7

private static void printFileJava7() throws IOException {


try (FileInputStream input = new FileInputStream("file.txt")) {
int data = input.read();
while (data != -1){
System.out.print((char) data);
data = input.read();
}
}
}

https://riptutorial.com/ 193
The try-with-resources statement can be used with any object that implements the Closeable or
AutoCloseable interface. It ensures that each resource is closed by the end of the statement. The
difference between the two interfaces is, that the close() method of Closeable throws an
IOException which has to be handled in some way.

In cases where the resource has already been opened but should be safely closed after use, one
can assign it to a local variable inside the try-with-resources

Java SE 7

private static void printFileJava7(InputStream extResource) throws IOException {


try (InputStream input = extResource) {
... //access resource
}
}

The local resource variable created in the try-with-resources constructor is effectively final.

Pitfall: memory leaks

Java manages memory automatically. You are not required to free memory manually. An object's
memory on the heap may be freed by a garbage collector when the object is no longer reachable
by a live thread.

However, you can prevent memory from being freed, by allowing objects to be reachable that are
no longer needed. Whether you call this a memory leak or memory packratting, the result is the
same -- an unnecessary increase in allocated memory.

Memory leaks in Java can happen in various ways, but the most common reason is everlasting
object references, because the garbage collector can’t remove objects from the heap while there
are still references to them.

Static fields

One can create such a reference by defining class with a static field containing some collection of
objects, and forgetting to set that static field to null after the collection is no longer needed. static
fields are considered GC roots and are never collected. Another issue is leaks in non-heap
memory when JNI is used.

Classloader leak

By far, though, the most insidious type of memory leak is the classloader leak. A classloader holds
a reference to every class it has loaded, and every class holds a reference to its classloader.
Every object holds a reference to its class as well. Therefore, if even a single object of a class
loaded by a classloader is not garbage, not a single class that that classloader has loaded can be
collected. Since each class also refers to its static fields, they cannot be collected either.

Accumulation leak The accumulation leak example could look like the following:

final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

https://riptutorial.com/ 194
final Deque<BigDecimal> numbers = new LinkedBlockingDeque<>();
final BigDecimal divisor = new BigDecimal(51);

scheduledExecutorService.scheduleAtFixedRate(() -> {
BigDecimal number = numbers.peekLast();
if (number != null && number.remainder(divisor).byteValue() == 0) {
System.out.println("Number: " + number);
System.out.println("Deque size: " + numbers.size());
}
}, 10, 10, TimeUnit.MILLISECONDS);

scheduledExecutorService.scheduleAtFixedRate(() -> {
numbers.add(new BigDecimal(System.currentTimeMillis()));
}, 10, 10, TimeUnit.MILLISECONDS);

try {
scheduledExecutorService.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}

This example creates two scheduled tasks. The first task takes the last number from a deque
called numbers, and, if the number is divisible by 51, it prints the number and the deque's size. The
second task puts numbers into the deque. Both tasks are scheduled at a fixed rate, and they run
every 10 ms.

If the code is executed, you’ll see that the size of the deque is permanently increasing. This will
eventually cause the deque to be filled with objects that consume all available heap memory.

To prevent this while preserving the semantics of this program, we can use a different method for
taking numbers from the deque: pollLast. Contrary to the method peekLast, pollLast returns the
element and removes it from the deque while peekLast only returns the last element.

Pitfall: using == to compare strings

A common mistake for Java beginners is to use the == operator to test if two strings are equal. For
example:

public class Hello {


public static void main(String[] args) {
if (args.length > 0) {
if (args[0] == "hello") {
System.out.println("Hello back to you");
} else {
System.out.println("Are you feeling grumpy today?");
}
}
}
}

The above program is supposed to test the first command line argument and print different
messages when it and isn't the word "hello". But the problem is that it won't work. That program
will output "Are you feeling grumpy today?" no matter what the first command line argument is.

https://riptutorial.com/ 195
In this particular case the String "hello" is put in the string pool while the String args[0] resides on
the heap. This means there are two objects representing the same literal, each with its reference.
Since == tests for references, not actual equality, the comparison will yield a false most of the
times. This doesn't mean that it will always do so.

When you use == to test strings, what you are actually testing is if two String objects are the same
Java object. Unfortunately, that is not what string equality means in Java. In fact, the correct way
to test strings is to use the equals(Object) method. For a pair of strings, we usually want to test if
they consist of the same characters in the same order.

public class Hello2 {


public static void main(String[] args) {
if (args.length > 0) {
if (args[0].equals("hello")) {
System.out.println("Hello back to you");
} else {
System.out.println("Are you feeling grumpy today?");
}
}
}
}

But it actually gets worse. The problem is that == will give the expected answer in some
circumstances. For example

public class Test1 {


public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
if (s1 == s2) {
System.out.println("same");
} else {
System.out.println("different");
}
}
}

Interestingly, this will print "same", even though we are testing the strings the wrong way. Why is
that? Because the Java Language Specification (Section 3.10.5: String Literals) stipulates that any
two string >>literals<< consisting of the same characters will actually be represented by the same
Java object. Hence, the == test will give true for equal literals. (The string literals are "interned" and
added to a shared "string pool" when your code is loaded, but that is actually an implementation
detail.)

To add to the confusion, the Java Language Specification also stipulates that when you have a
compile-time constant expression that concatenates two string literals, that is equivalent to a
single literal. Thus:

public class Test1 {


public static void main(String[] args) {
String s1 = "hello";
String s2 = "hel" + "lo";
String s3 = " mum";

https://riptutorial.com/ 196
if (s1 == s2) {
System.out.println("1. same");
} else {
System.out.println("1. different");
}
if (s1 + s3 == "hello mum") {
System.out.println("2. same");
} else {
System.out.println("2. different");
}
}
}

This will output "1. same" and "2. different". In the first case, the + expression is evaluated at
compile time and we compare one String object with itself. In the second case, it is evaluated at
run time and we compare two different String objects

In summary, using == to test strings in Java is almost always incorrect, but it is not guaranteed to
give the wrong answer.

Pitfall: testing a file before attempting to open it.

Some people recommend that you should apply various tests to a file before attempting to open it
either to provide better diagnostics or avoid dealing with exceptions. For example, this method
attempts to check if path corresponds to a readable file:

public static File getValidatedFile(String path) throws IOException {


File f = new File(path);
if (!f.exists()) throw new IOException("Error: not found: " + path);
if (!f.isFile()) throw new IOException("Error: Is a directory: " + path);
if (!f.canRead()) throw new IOException("Error: cannot read file: " + path);
return f;
}

You might use the above method like this:

File f = null;
try {
f = getValidatedFile("somefile");
} catch (IOException ex) {
System.err.println(ex.getMessage());
return;
}
try (InputStream is = new FileInputStream(file)) {
// Read data etc.
}

The first problem is in the signature for FileInputStream(File) because the compiler will still insist
we catch IOException here, or further up the stack.

The second problem is that checks performed by getValidatedFile do not guarantee that the
FileInputStream will succeed.

https://riptutorial.com/ 197
• Race conditions: another thread or a separate process could rename the file, delete the file,
or remove read access after the getValidatedFile returns. That would lead to a "plain"
IOException without the custom message.

• There are edge cases not covered by those tests. For example, on a system with SELinux in
"enforcing" mode, an attempt to read a file can fail despite canRead() returning true.

The third problem is that the tests are inefficient. For example, the exists, isFile and canRead calls
will each make a syscall to perform the required check. Another syscall is then made to open the
file, which repeats the same checks behind the scenes.

In short, methods like getValidatedFile are misguided. It is better to simply attempt to open the file
and handle the exception:

try (InputStream is = new FileInputStream("somefile")) {


// Read data etc.
} catch (IOException ex) {
System.err.println("IO Error processing 'somefile': " + ex.getMessage());
return;
}

If you wanted to distinguish IO errors thrown while opening and reading, you could use a nested
try / catch. If you wanted to produce better diagnostics for open failures, you could perform the
exists, isFile and canRead checks in the handler.

Pitfall: thinking of variables as objects

No Java variable represents an object.

String foo; // NOT AN OBJECT

Neither does any Java array contain objects.

String bar[] = new String[100]; // No member is an object.

If you mistakenly think of variables as objects, the actual behavior of the Java language will
surprise you.

• For Java variables which have a primitive type (such as int or float) the variable holds a
copy of the value. All copies of a primitive value are indistinguishable; i.e. there is only one
int value for the number one. Primitive values are not objects and they do not behave like
objects.

• For Java variables which have a reference type (either a class or an array type) the variable
holds a reference. All copies of a reference are indistinguishable. References may point to
objects, or they may be null which means that they point to no object. However, they are not
objects and they don't behave like objects.

Variables are not objects in either case, and they don't contain objects in either case. They may

https://riptutorial.com/ 198
contain references to objects, but that is saying something different.

Example class
The examples that follow use this class, which represents a point in 2D space.

public final class MutableLocation {


public int x;
public int y;

public MutableLocation(int x, int y) {


this.x = x;
this.y = y;
}

public boolean equals(Object other) {


if (!(other instanceof MutableLocation) {
return false;
}
MutableLocation that = (MutableLocation) other;
return this.x == that.x && this.y == that.y;
}
}

An instance of this class is an object that has two fields x and y which have the type int.

We can have many instances of the MutableLocation class. Some will represent the same locations
in 2D space; i.e. the respective values of x and y will match. Others will represent different
locations.

Multiple variables can point to the same object

MutableLocation here = new MutableLocation(1, 2);


MutableLocation there = here;
MutableLocation elsewhere = new MutableLocation(1, 2);

In the above, we have declared three variables here, there and elsewhere that can hold references
to MutableLocation objects.

If you (incorrectly) think of these variables as being objects, then you are likely to misread the
statements as saying:

1. Copy the location "[1, 2]" to here


2. Copy the location "[1, 2]" to there
3. Copy the location "[1, 2]" to elsewhere

From that, you are likely to infer we have three independent objects in the three variables. In fact
there are only two objects created by the above. The variables here and there actually refer to the
same object.

We can demonstrate this. Assuming the variable declarations as above:

https://riptutorial.com/ 199
System.out.println("BEFORE: here.x is " + here.x + ", there.x is " + there.x +
"elsewhere.x is " + elsewhere.x);
here.x = 42;
System.out.println("AFTER: here.x is " + here.x + ", there.x is " + there.x +
"elsewhere.x is " + elsewhere.x);

This will output the following:

BEFORE: here.x is 1, there.x is 1, elsewhere.x is 1


AFTER: here.x is 42, there.x is 42, elsewhere.x is 1

We assigned a new value to here.x and it changed the value that we see via there.x. They are
referring to the same object. But the value that we see via elsewhere.x has not changed, so
elsewhere must refer to a different object.

If a variable was an object, then the assignment here.x = 42 would not change there.x.

The equality operator does NOT test that two objects are
equal
Applying the equality (==) operator to reference values tests if the values refer to the same object.
It does not test whether two (different) objects are "equal" in the intuitive sense.

MutableLocation here = new MutableLocation(1, 2);


MutableLocation there = here;
MutableLocation elsewhere = new MutableLocation(1, 2);

if (here == there) {
System.out.println("here is there");
}
if (here == elsewhere) {
System.out.println("here is elsewhere");
}

This will print "here is there", but it won't print "here is elsewhere". (The references in here and
elsewhere are for two distinct objects.)

By contrast, if we call the equals(Object) method that we implemented above, we are going to test
if two MutableLocation instances have an equal location.

if (here.equals(there)) {
System.out.println("here equals there");
}
if (here.equals(elsewhere)) {
System.out.println("here equals elsewhere");
}

This will print both messages. In particular, here.equals(elsewhere) returns true because the
semantic criteria we chose for equality of two MutableLocation objects has been satisfied.

https://riptutorial.com/ 200
Method calls do NOT pass objects at all
Java method calls use pass by value1 to pass arguments and return a result.

When you pass a reference value to a method, you're actually passing a reference to an object by
value, which means that it is creating a copy of the object reference.

As long as both object references are still pointing to the same object, you can modify that object
from either reference, and this is what causes confusion for some.

However, you are not passing an object by reference2. The distinction is that if the object
reference copy is modified to point to another object, the original object reference will still point to
the original object.

void f(MutableLocation foo) {


foo = new MutableLocation(3, 4); // Point local foo at a different object.
}

void g() {
MutableLocation foo = MutableLocation(1, 2);
f(foo);
System.out.println("foo.x is " + foo.x); // Prints "foo.x is 1".
}

Neither are you passing a copy of the object.

void f(MutableLocation foo) {


foo.x = 42;
}

void g() {
MutableLocation foo = new MutableLocation(0, 0);
f(foo);
System.out.println("foo.x is " + foo.x); // Prints "foo.x is 42"
}

1 - In languages like Python and Ruby, the term "pass by sharing" is preferred for "pass by value" of an object /
reference.

2 - The term "pass by reference" or "call by reference" has a very specific meaning in programming language
terminology. In effect, it means that you pass the address of a variable or an array element, so that when the called
method assigns a new value to the formal argument, it changes the value in the original variable. Java does not
support this. For a more fulsome description of different mechanisms for passing parameters, please refer to
https://en.wikipedia.org/wiki/Evaluation_strategy.

Pitfall: combining assignment and side-effects

Occasionally we see StackOverflow Java questions (and C or C++ questions) that ask what
something like this:

i += a[i++] + b[i--];

https://riptutorial.com/ 201
evaluates to ... for some known initial states of i, a and b.

Generally speaking:

• for Java the answer is always specified1, but non-obvious, and often difficult to figure out
• for C and C++ the answer is often unspecified.

Such examples are often used in exams or job interviews as an attempt to see if the student or
interviewee understands how expression evaluation really works in the Java programming
language. This is arguably legitimate as a "test of knowledge", but that does not mean that you
should ever do this in a real program.

To illustrate, the following seemingly simple example has appeared a few times in StackOverflow
questions (like this one). In some cases, it appears as a genuine mistake in someone's code.

int a = 1;
a = a++;
System.out.println(a); // What does this print.

Most programmers (including Java experts) reading those statements quickly would say that it
outputs 2. In fact, it outputs 1. For a detailed explanation of why, please read this Answer.

However the real takeaway from this and similar examples is that any Java statement that both
assigns to and side-effects the same variable is going to be at best hard to understand, and at
worst downright misleading. You should avoid writing code like this.

1 - modulo potential issues with the Java Memory Model if the variables or objects are visible to other threads.

Pitfall: Not understanding that String is an immutable class

New Java programmers often forget, or fail to fully comprehend, that the Java String class is
immutable. This leads to problems like the one in the following example:

public class Shout {


public static void main(String[] args) {
for (String s : args) {
s.toUpperCase();
System.out.print(s);
System.out.print(" ");
}
System.out.println();
}
}

The above code is supposed to print command line arguments in upper case. Unfortunately, it
does not work, the case of the arguments is not changed. The problem is this statement:

s.toUpperCase();

You might think that calling toUpperCase() is going to change s to an uppercase string. It doesn't. It

https://riptutorial.com/ 202
can't! String objects are immutable. They cannot be changed.

In reality, the toUpperCase() method returns a String object which is an uppercase version of the
String that you call it on. This will probably be a new String object, but if s was already all
uppercase, the result could be the existing string.

So in order to use this method effectively, you need to use the object returned by the method call;
for example:

s = s.toUpperCase();

In fact, the "strings never change" rule applies to all String methods. If you remember that, then
you can avoid a whole category of beginner's mistakes.

Read Common Java Pitfalls online: https://riptutorial.com/java/topic/4388/common-java-pitfalls

https://riptutorial.com/ 203
Chapter 32: Comparable and Comparator
Syntax
• public class MyClass implements Comparable<MyClass>
• public class MyComparator implements Comparator<SomeOtherClass>
• public int compareTo(MyClass other)
• public int compare(SomeOtherClass o1, SomeOtherClass o2)

Remarks
When implementing a compareTo(..) method which depends upon a double, do not do the
following:

public int comareTo(MyClass other) {


return (int)(doubleField - other.doubleField); //THIS IS BAD
}

The truncation caused by the (int) cast will cause the method to sometimes incorrectly return 0
instead of a positive or negative number, and can thus lead to comparison and sorting bugs.

Instead, the simplest correct implementation is to use Double.compare, as such:

public int comareTo(MyClass other) {


return Double.compare(doubleField,other.doubleField); //THIS IS GOOD
}

A non-generic version of Comparable<T>, simply Comparable, has existed since Java 1.2. Other than
for interfacing with legacy code, it's always better to implement the generic version Comparable<T>,
as it doesn't require casting upon comparison.

It is very standard for a class to be comparable to itself, as in:

public class A implements Comparable<A>

While it is possible to break from this paradigm, be cautious when doing so.

A Comparator<T> can still be used on instances of a class if that class implements Comparable<T>. In
this case, the Comparator's logic will be used; the natural ordering specified by the Comparable
implementation will be ignored.

Examples

https://riptutorial.com/ 204
Sorting a List using Comparable or a Comparator

Say we are working on a class representing a Person by their first and last names. We have
created a basic class to do this and implemented proper equals and hashCode methods.

public class Person {

private final String lastName; //invariant - nonnull


private final String firstName; //invariant - nonnull

public Person(String firstName, String lastName){


this.firstName = firstName != null ? firstName : "";
this.lastName = lastName != null ? lastName : "";
}

public String getFirstName() {


return firstName;
}

public String getLastName() {


return lastName;
}

public String toString() {


return lastName + ", " + firstName;
}

@Override
public boolean equals(Object o) {
if (! (o instanceof Person)) return false;
Person p = (Person)o;
return firstName.equals(p.firstName) && lastName.equals(p.lastName);
}

@Override
public int hashCode() {
return Objects.hash(firstName, lastName);
}
}

Now we would like to sort a list of Person objects by their name, such as in the following scenario:

public static void main(String[] args) {


List<Person> people = Arrays.asList(new Person("John", "Doe"),
new Person("Bob", "Dole"),
new Person("Ronald", "McDonald"),
new Person("Alice", "McDonald"),
new Person("Jill", "Doe"));
Collections.sort(people); //This currently won't work.
}

Unfortunately, as marked, the above currently won't compile. Collections.sort(..) only knows how
to sort a list if the elements in that list are comparable, or a custom method of comparison is given.

If you were asked to sort the following list : 1,3,5,4,2, you'd have no problem saying the answer is
1,2,3,4,5. This is because Integers (both in Java and mathematically) have a natural ordering, a

https://riptutorial.com/ 205
standard, default comparison base ordering. To give our Person class a natural ordering, we
implement Comparable<Person>, which requires implementing the method compareTo(Person p):

public class Person implements Comparable<Person> {

private final String lastName; //invariant - nonnull


private final String firstName; //invariant - nonnull

public Person(String firstName, String lastName) {


this.firstName = firstName != null ? firstName : "";
this.lastName = lastName != null ? lastName : "";
}

public String getFirstName() {


return firstName;
}

public String getLastName() {


return lastName;
}

public String toString() {


return lastName + ", " + firstName;
}

@Override
public boolean equals(Object o) {
if (! (o instanceof Person)) return false;
Person p = (Person)o;
return firstName.equals(p.firstName) && lastName.equals(p.lastName);
}

@Override
public int hashCode() {
return Objects.hash(firstName, lastName);
}

@Override
public int compareTo(Person other) {
// If this' lastName and other's lastName are not comparably equivalent,
// Compare this to other by comparing their last names.
// Otherwise, compare this to other by comparing their first names
int lastNameCompare = lastName.compareTo(other.lastName);
if (lastNameCompare != 0) {
return lastNameCompare;
} else {
return firstName.compareTo(other.firstName);
}
}
}

Now, the main method given will function correctly

public static void main(String[] args) {


List<Person> people = Arrays.asList(new Person("John", "Doe"),
new Person("Bob", "Dole"),
new Person("Ronald", "McDonald"),
new Person("Alice", "McDonald"),
new Person("Jill", "Doe"));

https://riptutorial.com/ 206
Collections.sort(people); //Now functions correctly

//people is now sorted by last name, then first name:


// --> Jill Doe, John Doe, Bob Dole, Alice McDonald, Ronald McDonald
}

If, however, you either do not want or are unable to modify class Person, you can provide a custom
Comparator<T> that handles the comparison of any two Person objects. If you were asked to sort the
following list: circle, square, rectangle, triangle, hexagon you could not, but if you were asked to
sort that list based on the number of corners, you could. Just so, providing a comparator instructs
Java how to compare two normally not comparable objects.

public class PersonComparator implements Comparator<Person> {

public int compare(Person p1, Person p2) {


// If p1's lastName and p2's lastName are not comparably equivalent,
// Compare p1 to p2 by comparing their last names.
// Otherwise, compare p1 to p2 by comparing their first names
if (p1.getLastName().compareTo(p2.getLastName()) != 0) {
return p1.getLastName().compareTo(p2.getLastName());
} else {
return p1.getFirstName().compareTo(p2.getFirstName());
}
}
}

//Assume the first version of Person (that does not implement Comparable) is used here
public static void main(String[] args) {
List<Person> people = Arrays.asList(new Person("John", "Doe"),
new Person("Bob", "Dole"),
new Person("Ronald", "McDonald"),
new Person("Alice", "McDonald"),
new Person("Jill", "Doe"));
Collections.sort(people); //Illegal, Person doesn't implement Comparable.
Collections.sort(people, new PersonComparator()); //Legal

//people is now sorted by last name, then first name:


// --> Jill Doe, John Doe, Bob Dole, Alice McDonald, Ronald McDonald
}

Comparators can also be created/used as an anonymous inner class

//Assume the first version of Person (that does not implement Comparable) is used here
public static void main(String[] args) {
List<Person> people = Arrays.asList(new Person("John", "Doe"),
new Person("Bob", "Dole"),
new Person("Ronald", "McDonald"),
new Person("Alice", "McDonald"),
new Person("Jill", "Doe"));
Collections.sort(people); //Illegal, Person doesn't implement Comparable.

Collections.sort(people, new PersonComparator()); //Legal

//people is now sorted by last name, then first name:


// --> Jill Doe, John Doe, Bob Dole, Alice McDonald, Ronald McDonald

//Anonymous Class

https://riptutorial.com/ 207
Collections.sort(people, new Comparator<Person>() { //Legal
public int compare(Person p1, Person p2) {
//Method code...
}
});
}

Java SE 8

Lambda expression based comparators


As of Java 8, comparators can also be expressed as lambda expressions

//Lambda
Collections.sort(people, (p1, p2) -> { //Legal
//Method code....
});

Comparator default methods


Furthermore, there are interesting default methods on the Comparator interface for building
comparators : the following builds a comparator comparing by lastName and then firstName.

Collections.sort(people, Comparator.comparing(Person::getLastName)
.thenComparing(Person::getFirstName));

Inversing the order of a comparator


Any comparator can also easily be reversed using the reversedMethod which will change ascending
order to descending.

The compareTo and compare Methods

The Comparable<T> interface requires one method:

public interface Comparable<T> {

public int compareTo(T other);

And the Comparator<T> interface requires one method:

public interface Comparator<T> {

public int compare(T t1, T t2);

https://riptutorial.com/ 208
}

These two methods do essentially the same thing, with one minor difference: compareTo compares
this to other, whereas compare compares t1 to t2, not caring at all about this.

Aside from that difference, the two methods have similar requirements. Specifically (for
compareTo), Compares this object with the specified object for order. Returns a negative integer,
zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
Thus, for the comparison of a and b:

• If a < b, a.compareTo(b) and compare(a,b) should return a negative integer, and b.compareTo(a)
and compare(b,a) should return a positive integer
• If a > b, a.compareTo(b) and compare(a,b) should return a positive integer, and b.compareTo(a)
and compare(b,a) should return a negative integer
• If a equals b for comparison, all comparisons should return 0.

Natural (comparable) vs explicit (comparator) sorting

There are two Collections.sort() methods:

• One that takes a List<T> as a parameter where T must implement Comparable and override
the compareTo() method that determines sort order.
• One that takes a List and a Comparator as the arguments, where the Comparator
determines the sort order.

First, here is a Person class that implements Comparable:

public class Person implements Comparable<Person> {


private String name;
private int age;

public String getName() {


return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

@Override
public int compareTo(Person o) {
return this.getAge() - o.getAge();
}
@Override
public String toString() {
return this.getAge()+"-"+this.getName();
}

https://riptutorial.com/ 209
Here is how you would use the above class to sort a List in the natural ordering of its elements,
defined by the compareTo() method override:

//-- usage
List<Person> pList = new ArrayList<Person>();
Person p = new Person();
p.setName("A");
p.setAge(10);
pList.add(p);
p = new Person();
p.setName("Z");
p.setAge(20);
pList.add(p);
p = new Person();
p.setName("D");
p.setAge(30);
pList.add(p);

//-- natural sorting i.e comes with object implementation, by age


Collections.sort(pList);

System.out.println(pList);

Here is how you would use an anonymous inline Comparator to sort a List that does not
implement Comparable, or in this case, to sort a List in an order other than the natural ordering:

//-- explicit sorting, define sort on another property here goes with name
Collections.sort(pList, new Comparator<Person>() {

@Override
public int compare(Person o1, Person o2) {
return o1.getName().compareTo(o2.getName());
}
});
System.out.println(pList);

Sorting Map entries

As of Java 8, there are default methods on the Map.Entry interface to allow sorting of map
iterations.

Java SE 8

Map<String, Integer> numberOfEmployees = new HashMap<>();


numberOfEmployees.put("executives", 10);
numberOfEmployees.put("human ressources", 32);
numberOfEmployees.put("accounting", 12);
numberOfEmployees.put("IT", 100);

// Output the smallest departement in terms of number of employees


numberOfEmployees.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.limit(1)
.forEach(System.out::println); // outputs : executives=10

https://riptutorial.com/ 210
Of course, these can also be used outside of the stream api :

Java SE 8

List<Map.Entry<String, Integer>> entries = new ArrayList<>(numberOfEmployees.entrySet());


Collections.sort(entries, Map.Entry.comparingByValue());

Creating a Comparator using comparing method

Comparator.comparing(Person::getName)

This creates a comparator for the class Person that uses this person name as the comparison
source. Also it is possible to use method version to compare long, int and double. For example:

Comparator.comparingInt(Person::getAge)

Reversed order

To create a comparator that imposes the reverse ordering use reversed() method:

Comparator.comparing(Person::getName).reversed()

Chain of comparators

Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName)

This will create a comparator that firs compares with last name then compares with first name.
You can chain as many comparators as you want.

Read Comparable and Comparator online: https://riptutorial.com/java/topic/3137/comparable-and-


comparator

https://riptutorial.com/ 211
Chapter 33: CompletableFuture
Introduction
CompletableFuture is a class added to Java SE 8 which implements the Future interface from
Java SE 5. In addition to supporting the Future interface it adds many methods that allow
asynchronous callback when the future is completed.

Examples
Convert blocking method to asynchonous

The following method will take a second or two depending on your connection to retrieve a web
page and count the text length. Whatever thread calls it will block for that period of time. Also it
rethrows an exception which is useful later on.

public static long blockingGetWebPageLength(String urlString) {


try (BufferedReader br = new BufferedReader(new InputStreamReader(new
URL(urlString).openConnection().getInputStream()))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
return sb.toString().length();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}

This converts it to a method that will return immediately by moving the blocking method call to
another thread. By default the supplyAsync method will run the supplier on the common pool. For
a blocking method this is probably not a good choice since one might exhaust the threads in that
pool which is why I added the optional service parameter.

static private ExecutorService service = Executors.newCachedThreadPool();

static public CompletableFuture<Long> asyncGetWebPageLength(String url) {


return CompletableFuture.supplyAsync(() -> blockingGetWebPageLength(url), service);
}

To use the function in an asynchronous fashion one should use on of the methods that accepts a
lamda to be called with the result of the of the supplier when it completes such as thenAccept.
Also it is important to use exceptionally or handle method to log any exceptions that might have
happened.

public static void main(String[] args) {

https://riptutorial.com/ 212
asyncGetWebPageLength("https://stackoverflow.com/")
.thenAccept(l -> {
System.out.println("Stack Overflow returned " + l);
})
.exceptionally((Throwable throwable) -> {
Logger.getLogger("myclass").log(Level.SEVERE, "", throwable);
return null;
});

Simple Example of CompletableFuture

In the example below, the calculateShippingPrice method calculates shipping cost, which takes
some processing time. In a real world example, this would e.g. be contacting another server which
returns the price based on the weight of the product and the shipping method.

By modeling this in an async way via CompletableFuture, we can continue different work in the
method (i.e. calculating packaging costs).

public static void main(String[] args) {


int price = 15; // Let's keep it simple and work with whole number prices here
int weightInGrams = 900;

calculateShippingPrice(weightInGrams) // Here, we get the future


.thenAccept(shippingPrice -> { // And then immediately work on it!
// This fluent style is very useful for keeping it concise
System.out.println("Your total price is: " + (price + shippingPrice));
});
System.out.println("Please stand by. We are calculating your total price.");
}

public static CompletableFuture<Integer> calculateShippingPrice(int weightInGrams) {


return CompletableFuture.supplyAsync(() -> {
// supplyAsync is a factory method that turns a given
// Supplier<U> into a CompletableFuture<U>

// Let's just say each 200 grams is a new dollar on your shipping costs
int shippingCosts = weightInGrams / 200;

try {
Thread.sleep(2000L); // Now let's simulate some waiting time...
} catch(InterruptedException e) { /* We can safely ignore that */ }

return shippingCosts; // And send the costs back!


});
}

Read CompletableFuture online: https://riptutorial.com/java/topic/10935/completablefuture

https://riptutorial.com/ 213
Chapter 34: Concurrent Collections
Introduction
A concurrent collection is a [collection][1] which permits access by more than one thread at the
same time. Different threads can typically iterate through the contents of the collection and add or
remove elements. The collection is responsible for ensuring that the collection doesn't become
corrupt. [1]:
http://stackoverflow.com/documentation/java/90/collections#t=201612221936497298484

Examples
Thread-safe Collections

By default, the various Collection types are not thread-safe.

However, it's fairly easy to make a collection thread-safe.

List<String> threadSafeList = Collections.synchronizedList(new ArrayList<String>());


Set<String> threadSafeSet = Collections.synchronizedSet(new HashSet<String>());
Map<String, String> threadSafeMap = Collections.synchronizedMap(new HashMap<String,
String>());

When you make a thread-safe collection, you should never access it through the original
collection, only through the thread-safe wrapper.

Java SE 5

Starting in Java 5, java.util.collections has several new thread-safe collections that don't need
the various Collections.synchronized methods.

List<String> threadSafeList = new CopyOnWriteArrayList<String>();


Set<String> threadSafeSet = new ConcurrentHashSet<String>();
Map<String, String> threadSafeMap = new ConcurrentHashMap<String, String>();

Concurrent Collections

Concurrent collections are a generalization of thread-safe collections, that allow for a broader
usage in a concurrent environment.

While thread-safe collections have safe element addition or removal from multiple threads, they do
not necessarily have safe iteration in the same context (one may not be able to safely iterate
through the collection in one thread, while another one modifies it by adding/removing elements).

This is where concurrent collections are used.

As iteration is often the base implementation of several bulk methods in collections, like addAll,

https://riptutorial.com/ 214
removeAll,or also collection copying (through a constructor, or other means), sorting, ... the use
case for concurrent collections is actually pretty large.

For example, the Java SE 5 java.util.concurrent.CopyOnWriteArrayList is a thread safe and


concurrent List implementation, its javadoc states :

The "snapshot" style iterator method uses a reference to the state of the array at the
point that the iterator was created. This array never changes during the lifetime of the
iterator, so interference is impossible and the iterator is guaranteed not to throw
ConcurrentModificationException.

Therefore, the following code is safe :

public class ThreadSafeAndConcurrent {

public static final List<Integer> LIST = new CopyOnWriteArrayList<>();

public static void main(String[] args) throws InterruptedException {


Thread modifier = new Thread(new ModifierRunnable());
Thread iterator = new Thread(new IteratorRunnable());
modifier.start();
iterator.start();
modifier.join();
iterator.join();
}

public static final class ModifierRunnable implements Runnable {


@Override
public void run() {
try {
for (int i = 0; i < 50000; i++) {
LIST.add(i);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

public static final class IteratorRunnable implements Runnable {


@Override
public void run() {
try {
for (int i = 0; i < 10000; i++) {
long total = 0;
for(Integer inList : LIST) {
total += inList;
}
System.out.println(total);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

https://riptutorial.com/ 215
Another concurrent collection regarding iteration is ConcurrentLinkedQueue, which states :

Iterators are weakly consistent, returning elements reflecting the state of the queue at
some point at or since the creation of the iterator. They do not throw
java.util.ConcurrentModificationException, and may proceed concurrently with other
operations. Elements contained in the queue since the creation of the iterator will be
returned exactly once.

One should check the javadocs to see if a collection is concurrent, or not. The attributes of the
iterator returned by the iterator() method ("fail fast", "weakly consistent", ...) is the most important
attribute to look for.

Thread safe but non concurrent examples


In the above code, changing the LIST declaration to

public static final List<Integer> LIST = Collections.synchronizedList(new ArrayList<>());

Could (and statistically will on most modern, multi CPU/core architectures) lead to exceptions.

Synchronized collections from the Collections utility methods are thread safe for addition/removal
of elements, but not iteration (unless the underlying collection being passed to it already is).

Insertion into ConcurrentHashMap

public class InsertIntoConcurrentHashMap


{

public static void main(String[] args)


{
ConcurrentHashMap<Integer, SomeObject> concurrentHashMap = new ConcurrentHashMap<>();

SomeObject value = new SomeObject();


Integer key = 1;

SomeObject previousValue = concurrentHashMap.putIfAbsent(1, value);


if (previousValue != null)
{
//Then some other value was mapped to key = 1. 'value' that was passed to
//putIfAbsent method is NOT inserted, hence, any other thread which calls
//concurrentHashMap.get(1) would NOT receive a reference to the 'value'
//that your thread attempted to insert. Decide how you wish to handle
//this situation.
}

else
{
//'value' reference is mapped to key = 1.
}
}
}

https://riptutorial.com/ 216
Read Concurrent Collections online: https://riptutorial.com/java/topic/8363/concurrent-collections

https://riptutorial.com/ 217
Chapter 35: Concurrent Programming
(Threads)
Introduction
Concurrent computing is a form of computing in which several computations are executed
concurrently instead of sequentially. Java language is designed to support concurrent
programming through the usage of threads. Objects and resources can be accessed by multiple
threads; each thread can potentially access any object in the program and the programmer must
ensure read and write access to objects is properly synchronized between threads.

Remarks
Related topic(s) on StackOverflow:

• Atomic Types
• Executor, ExecutorService and Thread pools
• Extending Thread versus implementing Runnable

Examples
Basic Multithreading

If you have many tasks to execute, and all these tasks are not dependent of the result of the
precedent ones, you can use Multithreading for your computer to do all this tasks at the same
time using more processors if your computer can. This can make your program execution faster if
you have some big independent tasks.

class CountAndPrint implements Runnable {

private final String name;

CountAndPrint(String name) {
this.name = name;
}

/** This is what a CountAndPrint will do */


@Override
public void run() {
for (int i = 0; i < 10000; i++) {
System.out.println(this.name + ": " + i);
}
}

public static void main(String[] args) {


// Launching 4 parallel threads
for (int i = 1; i <= 4; i++) {
// `start` method will call the `run` method

https://riptutorial.com/ 218
// of CountAndPrint in another thread
new Thread(new CountAndPrint("Instance " + i)).start();
}

// Doing some others tasks in the main Thread


for (int i = 0; i < 10000; i++) {
System.out.println("Main: " + i);
}
}
}

The code of the run method of the various CountAndPrint instances will execute in non predictable
order. A snippet of a sample execution might look like this:

Instance 4: 1
Instance 2: 1
Instance 4: 2
Instance 1: 1
Instance 1: 2
Main: 1
Instance 4: 3
Main: 2
Instance 3: 1
Instance 4: 4
...

Producer-Consumer

A simple example of producer-consumer problem solution. Notice that JDK classes (AtomicBoolean
and BlockingQueue) are used for synchronization, which reduces the chance of creating an invalid
solution. Consult Javadoc for various types of BlockingQueue; choosing different implementation
may drastically change the behavior of this example (like DelayQueue or Priority Queue).

public class Producer implements Runnable {

private final BlockingQueue<ProducedData> queue;

public Producer(BlockingQueue<ProducedData> queue) {


this.queue = queue;
}

public void run() {


int producedCount = 0;
try {
while (true) {
producedCount++;
//put throws an InterruptedException when the thread is interrupted
queue.put(new ProducedData());
}
} catch (InterruptedException e) {
// the thread has been interrupted: cleanup and exit
producedCount--;
//re-interrupt the thread in case the interrupt flag is needeed higher up
Thread.currentThread().interrupt();
}
System.out.println("Produced " + producedCount + " objects");

https://riptutorial.com/ 219
}
}

public class Consumer implements Runnable {

private final BlockingQueue<ProducedData> queue;

public Consumer(BlockingQueue<ProducedData> queue) {


this.queue = queue;
}

public void run() {


int consumedCount = 0;
try {
while (true) {
//put throws an InterruptedException when the thread is interrupted
ProducedData data = queue.poll(10, TimeUnit.MILLISECONDS);
// process data
consumedCount++;
}
} catch (InterruptedException e) {
// the thread has been interrupted: cleanup and exit
consumedCount--;
//re-interrupt the thread in case the interrupt flag is needeed higher up
Thread.currentThread().interrupt();
}
System.out.println("Consumed " + consumedCount + " objects");
}
}

public class ProducerConsumerExample {


static class ProducedData {
// empty data object
}

public static void main(String[] args) throws InterruptedException {


BlockingQueue<ProducedData> queue = new ArrayBlockingQueue<ProducedData>(1000);
// choice of queue determines the actual behavior: see various BlockingQueue
implementations

Thread producer = new Thread(new Producer(queue));


Thread consumer = new Thread(new Consumer(queue));

producer.start();
consumer.start();

Thread.sleep(1000);
producer.interrupt();
Thread.sleep(10);
consumer.interrupt();
}
}

Using ThreadLocal

A useful tool in Java Concurrency is ThreadLocal – this allows you to have a variable that will be
unique to a given thread. Thus, if the same code runs in different threads, these executions will not
share the value, but instead each thread has its own variable that is local to the thread.

https://riptutorial.com/ 220
For example, this is frequently used to establish the context (such as authorization information) of
handling a request in a servlet. You might do something like this:

private static final ThreadLocal<MyUserContext> contexts = new ThreadLocal<>();

public static MyUserContext getContext() {


return contexts.get(); // get returns the variable unique to this thread
}

public void doGet(...) {


MyUserContext context = magicGetContextFromRequest(request);
contexts.put(context); // save that context to our thread-local - other threads
// making this call don't overwrite ours
try {
// business logic
} finally {
contexts.remove(); // 'ensure' removal of thread-local variable
}
}

Now, instead of passing MyUserContext into every single method, you can instead use
MyServlet.getContext() where you need it. Now of course, this does introduce a variable that needs
to be documented, but it’s thread-safe, which eliminates a lot of the downsides to using such a
highly scoped variable.

The key advantage here is that every thread has its own thread local variable in that contexts
container. As long as you use it from a defined entry point (like demanding that each servlet
maintains its context, or perhaps by adding a servlet filter) you can rely on this context being there
when you need it.

CountDownLatch

CountDownLatch

A synchronization aid that allows one or more threads to wait until a set of operations
being performed in other threads completes.

1. A CountDownLatch is initialized with a given count.


2. The await methods block until the current count reaches zero due to invocations of the
countDown() method, after which all waiting threads are released and any subsequent
invocations of await return immediately.
3. This is a one-shot phenomenon—the count cannot be reset. If you need a version that resets
the count, consider using a CyclicBarrier.

Key Methods:

public void await() throws InterruptedException

Causes the current thread to wait until the latch has counted down to zero, unless the
thread is interrupted.

https://riptutorial.com/ 221
public void countDown()

Decrements the count of the latch, releasing all waiting threads if the count reaches
zero.

Example:

import java.util.concurrent.*;

class DoSomethingInAThread implements Runnable {


CountDownLatch latch;
public DoSomethingInAThread(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
System.out.println("Do some thing");
latch.countDown();
} catch(Exception err) {
err.printStackTrace();
}
}
}

public class CountDownLatchDemo {


public static void main(String[] args) {
try {
int numberOfThreads = 5;
if (args.length < 1) {
System.out.println("Usage: java CountDownLatchDemo numberOfThreads");
return;
}
try {
numberOfThreads = Integer.parseInt(args[0]);
} catch(NumberFormatException ne) {

}
CountDownLatch latch = new CountDownLatch(numberOfThreads);
for (int n = 0; n < numberOfThreads; n++) {
Thread t = new Thread(new DoSomethingInAThread(latch));
t.start();
}
latch.await();
System.out.println("In Main thread after completion of " + numberOfThreads + "
threads");
} catch(Exception err) {
err.printStackTrace();
}
}
}

output:

java CountDownLatchDemo 5
Do some thing
Do some thing
Do some thing
Do some thing

https://riptutorial.com/ 222
Do some thing
In Main thread after completion of 5 threads

Explanation:

1. CountDownLatch is initialized with a counter of 5 in Main thread


2. Main thread is waiting by using await() method.
3. Five instances of DoSomethingInAThread have been created. Each instance decremented the
counter with countDown() method.
4. Once the counter becomes zero, Main thread will resume

Synchronization

In Java, there is a built-in language-level locking mechanism: the synchronized block, which can
use any Java object as an intrinsic lock (i.e. every Java object may have a monitor associated with
it).

Intrinsic locks provide atomicity to groups of statements. To understand what that means for us,
let's have a look at an example where synchronized is useful:

private static int t = 0;


private static Object mutex = new Object();

public static void main(String[] args) {


ExecutorService executorService = Executors.newFixedThreadPool(400); // The high thread
count is for demonstration purposes.
for (int i = 0; i < 100; i++) {
executorService.execute(() -> {
synchronized (mutex) {
t++;
System.out.println(MessageFormat.format("t: {0}", t));
}
});
}
executorService.shutdown();
}

In this case, if it weren't for the synchronized block, there would have been multiple concurrency
issues involved. The first one would be with the post increment operator (it isn't atomic in itself),
and the second would be that we would be observing the value of t after an arbitrary amount of
other threads has had the chance to modify it. However, since we acquired an intrinsic lock, there
will be no race conditions here and the output will contain numbers from 1 to 100 in their normal
order.

Intrinsic locks in Java are mutexes (i.e. mutual execution locks). Mutual execution means that if
one thread has acquired the lock, the second will be forced to wait for the first one to release it
before it can acquire the lock for itself. Note: An operation that may put the thread into the wait
(sleep) state is called a blocking operation. Thus, acquiring a lock is a blocking operation.

Intrinsic locks in Java are reentrant. This means that if a thread attempts to acquire a lock it
already owns, it will not block and it will successfully acquire it. For instance, the following code will

https://riptutorial.com/ 223
not block when called:

public void bar(){


synchronized(this){
...
}
}
public void foo(){
synchronized(this){
bar();
}
}

Beside synchronized blocks, there are also synchronized methods.

The following blocks of code are practically equivalent (even though the bytecode seems to be
different):

1. synchronized block on this:

public void foo() {


synchronized(this) {
doStuff();
}
}

2. synchronized method:

public synchronized void foo() {


doStuff();
}

Likewise for static methods, this:

class MyClass {
...
public static void bar() {
synchronized(MyClass.class) {
doSomeOtherStuff();
}
}
}

has the same effect as this:

class MyClass {
...
public static synchronized void bar() {
doSomeOtherStuff();
}
}

Atomic operations

https://riptutorial.com/ 224
An atomic operation is an operation that is executed "all at once", without any chance of other
threads observing or modifying state during the atomic operation's execution.

Lets consider a BAD EXAMPLE.

private static int t = 0;

public static void main(String[] args) {


ExecutorService executorService = Executors.newFixedThreadPool(400); // The high thread
count is for demonstration purposes.