2. Garbage Collection
Garbage collection is a process of managing the heap
efficiently; i.e., reclaiming memory occupied by
objects that are no longer needed and making it
available for new objects.
The automatic garbage collection scheme guarantees
that a reference to an object is always valid while the
object is needed by the program.
A program has no guarantees that the automatic
garbage collector will be run during its execution.
3. Garbage Collection continued
An object in the heap is said to be reachable if it is
referenced by any local reference in a runtime stack.
A reachable object is alive, and is accessible by one or
more live threads.
Any object that is not accessible by a live thread is a
candidate for garbage collection.
Garbage collection does not necessarily occur as soon
as an object becomes unreachable.
If a composite object becomes unreachable, its
constituent objects also become unreachable.
4. Object Finalization
It provides an object with a last resort to undertake any action
before its storage is reclaimed.
The automatic garbage collector calls the finalize() method
(finalizer) in an object that is eligible for garbage collection
before actually destroying the object.
The finalize() method is defined in the Object class.
Any exception thrown but not caught by a finalize method called
by the garbage collector is ignored, and the finalization of this
object is terminated.
The finalizer is only called once on an object, regardless of
whether any exception is thrown during its execution.
There is no guarantee that the finalizer will ever be called.
Unlike constructors overridden finalizers are not implicitly
chained.
5. Invoking Garbage Collector
Even though the garbage collecter can be invoked
explicitly, there are no guarantees that it will be run.
The System.gc() method can be used to request
garbage collection.
System.runFinalization() method can be called to
suggest that any pending finalizers be run for objects
eligible for garbage collection.
Above methods are from Runtime class whose object
can be obtained by calling the method
Runtime.getRuntime().
6. Java.util package
Locale class provide methods to format values that
represent dates, currency and numbers according to a
specific locale.
Date class represents time as a long integer which
represents time as the date and the time of day.
The Date class is not locale-sensitive, and has been
replaced by the Calendar and Date-Format classes.
A Calendar class represents a specific instant in time
that comprises a date and a time of day as in Date class
It is interoperable with the Date class and manipulated
using add(), set() and roll().
7. java.text Package
DateFormat class provides methods for formatting and
parsing dates and time.
The abstract class NumberFormat provides methods for
formatting and parsing numbers and currency values.
The factory methods of NumberFormat return an instance
of the concrete class java.text.DecimalFormat or an
instance of the final class java.util.Currency for
formatting numbers or currency values, respectively.
A number formatter can also be used to format a double or
a long values.
A number formatter can be used to parse strings that are
textual representations of numeric value.
8. String Pattern Matching
java.util.regex package provides support for string pattern
matching that is based on regular expressions.
The java.util.Pattern class allows to compile a regular
expression, and the java.util.Matcher class allows to
create an engine for string pattern matching with the
compiled regular expression.
A match is shown in the following notation:
(start_index,end_index:group) where start_index and
end_index are indices in target indicating where a pattern
match was found, and group comprises the character(s)
delineated by the two indices in the target, that matched
the pattern.
9. String Pattern Matching
Compiling the regular expression string into a Pattern
object which constitutes the compiled representation of
the regular expression.
Pattern pattern = Pattern.compile(regexStr);
Using the Pattern object to obtain a Matcher (i.e., an
engine) for applying the pattern to a specified input of type
java.lang.CharSequence.
Matcher matcher = pattern.matcher(input);
Using the operations of the matcher to apply the pattern to
the input:
boolean eureka = matcher.matches();
10. Java.util.Scanner
A scanner reads characters from a source and converts
them into tokens.
A token is a sequence of characters in the source that
comprises a formatted value.
It works in Tokenizing Mode, for tokenizing a stream of
formatted data values and Multi-Line Mode, for searching
or finding matches in line-oriented input.
It can accept input from “standard input stream” using
System.in and properly format the program output.
The methods of the Scanner class to read input or tokenize
input, are nextLine(), nextInt(), next(), hasNext(),
hasNextIntegralType(), hasNextLine(), skip(), match() etc.
11. Threads
The sequence of code executed for each task defines a
separate path of execution, which is called a thread.
It is an independent sequential path of execution within a
program.
Compared to processes, context switching between threads
is usually less expensive.
The cost of communication between threads is relatively
low then that between the processes.
Threads share the same address space, data and code.
All threads are created and controlled by a unique object of
the java.lang.Thread class in java.
12. Threads
The runtime environment distinguishes between user threads
and daemon threads.
When an application is run, a user thread is automatically
created to execute the main() method which is also called the
main thread.
Daemon threads exist only to serve user threads.
All other threads, called child threads, are spawned from the
main thread, inheriting its user-thread status
Calling the setDaemon(boolean) method in Thread class
marks the status of the thread as either daemon or user, but this
must be done before the thread is started.
When a GUI application is started, a special thread is created
automatically to monitor the user–GUI interaction even though
the main thread might have finished executing.
Threads are implemented in two ways:
• implementing the java.lang.Runnable interface.
• extending the java.lang.Thread class.
13. Runnable Interface
A Runnable interface has one abstract method:
public interface Runnable { void run(); }
A thread created from an object implementing the
Runnable interface, and will execute the code defined in
public method run().
The procedure for creating threads using Runnable
interface is:
1. A class implements the Runnable interface,
providing the run() method that will be executed by the
thread. An object of this class is a Runnable object.
2. An object of the Thread class is created by passing a
Runnable object as an argument in the Thread
constructor call.
3. The start() method is invoked on the Thread object
created in the previous step which returns immediately
after a thread has been spawned as start method is
asynchronous.
14. Constructors and methods from java.lang.Thread
Thread(Runnable threadTarget)
Thread(Runnable threadTarget, String threadName)
The argument threadTarget is the object whose run()
method is executed, and explicit name for the thread.
static Thread currentThread()
returns a reference to the Thread object of the currently
executing thread.
void run() as Thread class implements Runnable interface.
final void setDaemon(boolean flag)
final boolean isDaemon()
Sets the status of the thread either as a daemon thread or as
a user thread
void start()
Spawns a new thread as a child thread of the current thread
15. Creating Threads from Thread Class
Thread can also be created by extending Thread class.
1. A class extending the Thread class overrides the
run() method from the Thread class to define the code
executed by the thread.
2. This subclass may call a Thread constructor
explicitly in its constructors to initialize the thread,
using the super() call.
3. The start() method inherited from the Thread class
is invoked on the object of the class to make the thread
eligible for running.
16. Synchronization
A lock (also called a monitor) is used to synchronize access to a
shared resource.
Threads gain access to a shared resource by first acquiring the
lock associated with the resource.
At most one thread can hold the lock and thereby have access to
the shared resource i.e an object.
A thread must acquire the object lock associated with a shared
resource to access it and restore the lock when the thread exits
the shared resource.
Classes also have a class-specific lock that is analogous to the
object lock.
Two ways in which execution of code can be synchronized, either
by declaring synchronized methods or synchronized code blocks.
17. Synchronized Methods
Synchronized methods of an object can be executed only by a
single thread at a time.
A thread wishing to execute a synchronized method must first
obtain the object’s lock and waits if the object lock is held by
another thread.
A thread relinquishes the lock simply by returning from the
synchronized method.
While a thread is inside a synchronized method of an object, all
other threads that wish to execute this synchronized method or
any other synchronized method of the object will have to wait.
Such restriction does not apply to the thread that already has the
lock and is executing a synchronized method of the object.
Non-synchronized methods of the object can always be called at
any time by any thread.
Static methods synchronize on the class lock.
Synchronization of static methods in a class is independent from
the synchronization of instance methods on objects of the class.
18. Synchronized Blocks
Synchronized block allows execution of arbitrary code
to be synchronized on the lock of an arbitrary object.
Synchronized statement is as follows:
synchronized (<object reference expression>) {
<code>block> }
Usually the execution of the method is synchronized
on the lock of the current object.
No other thread is be able to execute the code block, or
any other code requiring the object lock which is
already acquired, until the lock is relinquished.
19. Thread States
New state: A thread has been created, but it has not
started yet. It starts using the start() method.
Ready-to-run state: A thread starts life in the Ready-to-
run state.
Running state: The thread is currently executing.
Dead state: Once in this state, the thread cannot ever run
again.
Non-runnable states : A running thread can transit to one
of the non-runnable states, depending on the
circumstances. It remains in a non-runnable state until a
special transition occurs. A thread first transits to the
Ready-to-run state before going to the Running state from
a non-runnable state.
20. Non Runnable States
❍ Sleeping: The thread sleeps for a specified amount
of time.
❍ Blocked for I/O: The thread waits for a blocking
operation to complete.
❍ Blocked for join completion: The thread awaits
completion of another thread.
❍ Waiting for notification: The thread awaits
notification from another thread.
❍ Blocked for lock acquisition: The thread waits to
acquire the lock of an object.
21. Running and Yielding
After start() method, the thread starts in the Ready-to-run
state and is eligible for running. It waits for its turn to get
CPU time. Once picked by thread scheduler it goes in
Running state.
A call to the method yield(), may cause the current thread
in the Running state to transit to the Ready-to-run state,
thus relinquishing the CPU, thus giving other threads in
the Ready-to-run state a chance to run.
The thread is then at the mercy of the thread scheduler as
to when it will run again, which is possible if there are no
threads in the Ready-to-run state.
The yield() method is an advisory method, and comes with
no guarantees that the JVM will carry out the call’s bidding.
A call to the yield() method does not affect any locks that
the thread might hold.
22. Sleeping and Waking up
A call to the method sleep() causes the currently
running thread to temporarily pause its execution and
transit to the Sleeping state.
Sleep method does not relinquish any lock that the
thread might have.
The thread will sleep for at least the time specified in
its argument, before transitioning to the Readyto-run
state where it takes its turn to run again.
If a thread is interrupted while sleeping, it will throw
an InterruptedException when it awakes and gets to
execute.
23. Waiting and Notifying
Waiting and notifying provide means of communication
between threads that synchronize on the same object.
Wait and Notify methods can only be executed on an object
whose lock the thread holds (synchronized code).
A thread invokes the wait() method on the object whose lock it
holds, as a condition for its continued execution was not met.
It leaves the Running state and transits to the Waiting-for
notification state, were it waits for the condition to occur.
Such a thread relinquishes the ownership of only the object lock
on which the wait() method was invoked.
Each object has a wait set containing threads waiting for
notification.
Hence another thread can acquire the object lock on the shared
object for its own purposes.
24. Waiting and Notifying
A thread in the Waiting-for-notification state can be awakened by the
occurrence of any one of these three incidents:
1. Another thread invokes the notify() method on the object of the waiting
thread, and the waiting thread is selected as the thread to be awakened.
2. The waiting thread times out.
3. Another thread interrupts the waiting thread
A thread invokes a notification method on the current object whose lock it
holds to notify thread(s) that are in the wait set of the object.
Invoking the notify() method on an object wakes up a single thread that is
waiting for the lock of the object. The selection of a thread to awaken is
dependent on the thread policies implemented by the JVM.
On being notified, a waiting thread first transits to the Blocked-for-lock-
acquisition state to acquire the lock on the object, and not directly to the
Ready-to-run state.
The notifying thread relinquishes the lock at its own discretion.
When the notified thread obtains the object lock, it is enabled for execution,
waiting in the Ready-to-run state for its turn to execute again. Finally, when it
does execute, the call to the wait() method returns and the thread can continue
with its execution.
25. Interrupted and Joining
A thread is interrupted when another thread invoked
the interrupt() method on the waiting thread.
When the thread is awakened, the return from the
wait() call will result in an InterruptedException if and
when the awakened thread finally gets a chance to run.
A thread can invoke the join() method on another
thread in order to wait for the other thread to complete
its execution before continuing.
Thread calling join waits until other thread completes
its execution, or waiting thread is timeout or
interrrupted.
26. Thread Termination and Deadlocks
A thread can transit to the Dead state from the Running or the
Ready-to-run states.
The thread dies when it completes its run() method, either by
returning normally or by throwing an exception.
Once in dead state, the thread cannot be resurrected.
There is no way the thread can be enabled for running again, not
even by calling the start() method again on the thread object.
A deadlock is a situation where a thread is waiting for an object
lock that another thread holds, and this second thread is waiting
for an object lock that the first thread holds.
Since each thread is waiting for the other thread to relinquish a
lock, they both remain waiting forever in the Blocked-for-lock-
acquisition state.
It can be avoided if threads acquire locks on the objects in same
order.
27. Generics
Generics allow reference types (classes, interfaces, and
array types) and methods to be parameterized with type
information.
An abstract data type (ADT) defines both the types of
objects and the operations that can be performed on these
objects.
Generics allow to specify the types used by the ADT, so that
the same definition of an ADT can be used on different
types of objects.
It provides type information in ADTs, allowing the
compiler to guarantee type-safety of operations at runtime.
They are implemented as compile-time transformations.
It eliminates the necessity of explicit type checking and
casting at runtime
28. Generic Type
A generic type is a reference type that defines a list of
formal type parameters or type variables (T1, T2, ..., Tn)
that must be provided before it can be used as a type.
A generic class is declared as class Node<E>, which allows
nodes of specific types to be maintained, with the formal
type parameter, E, representing the type of the data in a
node.
If a generic class has several formal type parameters, these
are specified as a comma separated list, <T1, T2, ..., Tn>.
The formal type E can be used like a reference type in the
class body: as a field type, return type, and as a parameter
type in the methods.
29. Formal Type Parameter
A constructor declaration in a generic class cannot
specify the formal type parameters of the generic class
in its constructor header after the class name.
A formal type parameter E cannot be used to create a
new instance, as it is not known which concrete type it
represents.
A formal type parameter is a non-static type and
cannot be used in a static context.
30. Parameterized types
Parameterized type is an invocation or instantiation of a generic
type, that is a specific usage of the generic type where the formal
type parameters are replaced by actual type parameters.
In generic type invocation, the actual type parameters are
passed in order to instantiate a generic type.
Generic type invocation example:
Node<Integer> intNode = new Node<Integer>(2008);
The actual type parameter Integer, explicitly specified in the
declaration statement above, binds to the formal type parameter
E. The compiler treats the parameterized type Node<Integer> as
a new type.
The parameterized type Node<Integer> constrains the generic
type Node<E> to Integer objects, thus implementing
homogenous nodes with Integers.
While calling a method, the actual type parameter is determined
from the type of the reference used to make the call.
31. Generic Interface
Generic interfaces is analogous to generic classes with same
specification of formal type parameters as in a generic
classes.
A generic interface can be implemented by a generic (or a
non-generic) class as follows:
class MonoNode<E> implements IMonoLink<E> { }
The first occurrence of <E> declares E to be a type
parameter, and the second occurrence of <E>
parameterizes the generic interface with this type
parameter.
The compiler checks that the formal type parameters of the
superclass in the extends clause can be resolved.
A subtype can inherit only one parameterization of the
same generic interface supertype.
32. Raw Types
A generic type without its formal type parameters is called
a raw type.
The raw type is the supertype of all parameterized types of
the generic class.
A parameterized type (e.g., Node<String>) is not a class
but are used by the compiler to check that objects created
are used correctly in the program.
The compiler does not create a new class for each
parameterized type and hence there is only one
implementation of a generic class.
Only reference types (excluding array creation and
enumerations) can be used in invocations of generic types.
33. Subtype Covariance
An argument of type Node<Integer> or Node<Double> cannot
be passed where a parameter of type Node<Number> is
expected.
Node<Integer> and Node<Double> are not subtypes of
Node<Number>, although Integer and Double are subtypes of
Number. Such type relationship is called subtype covariance.
The subtype covariance relationship holds for arrays because the
element type is available at runtime.
The subtype covariance relationship does not hold for
parameterized types that are instantiations of the same generic
type with different actual type parameters, regardless of any
subtyping relationship between the actual type parameters.
34. Wildcards
A wildcard type can represent many types.
A parameterized type that has wildcard card types as actual type
parameters can represent a family of types, in contrast to a
concrete parameterized type that only represents itself.
The Subtype Covariance, ? extends Type represents all subtypes
of Type (including Type itself) and is called upper bounded
wildcard.
Subtype Contravariance, ? super Type represents all supertypes
of Type (including Type itself) and is called lower bounded
wildcard.
Subtype Bivariance, ? represents all types and is called
unbounded wildcard.
Subtype Invariance, Type represents Type itself and is called
unbounded type parameter.
There is no subtype covariance relationship between concrete
parameterized types, but there is such relationship between
bounded parameterized types and concrete parameterized types
Wildcards cannot be used in instance creation expressions and
cannot be used in the header of reference type declarations.
35. Generic Methods and Constructors
A generic method is implemented like an ordinary method,
except that one or more formal type parameters are
specified immediately preceding the return type.
A generic constructor has formal parameters specified
before the class name in the constructor header.
A formal type parameter can be used in the return type, the
formal parameter list, and the method body.
It can also be used to specify bounds in the formal type
parameter list.
A generic method need not be declared in a generic type.
36. Equals method
Equals method implements the most discriminating
equivalence relation possible on objects.
Each instance of the class is only equal to itself.
Not overriding the equals() method appropriately makes it
impossible to search for objects in arrays, collections, or
maps.
The contains() method of the list relies on the equals()
method.
An implementation of the equals() method must satisfy
the properties of an equivalence relation such as Reflexive,
Symmetric, Transitive,Consistent and null comparison.
37. Hashcode Method
Hashing is an efficient technique for storing and retrieving
data.
A common hashing scheme uses an array where each
element is a list of items. The array elements are called
buckets.
Operations in a hashing scheme involve computing an
array index from an item.
Converting an item to its array index is done by a hash
function. The array index returned by the hash function is
called the hash value of the item.
The hash value identifies a particular bucket.
38. Hashcode method
Note that no duplicate items are stored.
Retrieving an item is based on using a key.
The key represents the identity of the item
Storing involves hashing the item to determine the bucket and if the
item does not match one already in the bucket, it is stored in the
bucket.
Retrieval involves hashing the key to determine the bucket and if the
key matches an item in the bucket, this item is retrieved from the
bucket.
Different items can hash to the same bucket.
Finding an item in the bucket entails a search and requires an equality
function to compare items.
An ideal hash function produces a uniform distribution of hash values
for a collection of items across all possible hash values.
A hash table contains key-value entries as items and the hashing is
done on the keys only to provide efficient lookup of values.
Equal objects must produce equal hash codes while inequality
places no restrictions on the hash value.
39. The Comparable<E> Interface
The natural ordering of objects is specified by
implementing the generic Comparable interface.
int compareTo(E o) is the method of Comparable interface
which returns a negative integer, zero, or a positive integer
if the current object is less than, equal to, or greater than
the specified object.
Objects implementing this interface can be used as
elements in a sorted set, keys in a sorted map and elements
in lists that are sorted manually using the Collections.sort()
method.
The equals() and the compareTo() methods should be
consistent.
40. The Comparator<E> Interface
Precise control of ordering can be achieved by creating
a customized comparator that imposes a specific total
ordering on the elements.
int compare(E o1, E o2) method returns a negative
integer, zero, or a positive integer if the first object is
less than, equal to, or greater than the second object,
according to the total ordering.
An alternative ordering to the default natural ordering
can be specified by passing a Comparator to the
constructor when the sorted set or map is created.
41. Java Collections Framework
A collection allows a group of objects to be treated as a
single unit.
Objects can be stored, retrieved, and manipulated as
elements of a collection.
The core framework in the java.util package comprises of
core generic interfaces, set of implementations of core
interfaces and an assortment of static utility methods found
in the Collections and Arrays classes.
Collection (or a map) only stores reference values of
objects, and not the actual objects.
Collections are manipulated according to their interface
types, rather than by the implementation types.
42. Core Interfaces
Collection<E> is a basic interface that defines the normal
operations that allow a collection of objects to be
maintained or handled as a single unit.
Set<E> extends Collection interface to represent its
mathematical namesake: a set of unique elements. E.g.
HashSet<E> and LinkedHashSet<E>.
SortedSet<E> extends the Set interface to provide the
required functionality for maintaining a set in which the
elements are stored in some sorted order.
NavigableSet<E> extends and replaces the SortedSet
interface to maintain a sorted set, and is the preferred
choice in new code.
List<E> extends the Collection interface to maintain a
sequence of elements that can contain duplicates. E.g.
ArrayList<E>, Vector<E>, LinkedList<E>.
43. Core Interfaces
Queue<E> extends the Collection interface to maintain a
collection whose elements need to be processed in some way,
i.e., insertion at one end and removal at the other, usually as
FIFO. E.g. PriorityQueue<E>, LinkedList<E>
Deque<E> extends the Queue interface to maintain a queue
whose elements can be processed at both ends. E.g.
ArrayDeque<E>, LinkedList<E>.
Map<K,V> is a basic interface that defines operations for
maintaining mappings of keys to values. It does not extends the
collection interface as a Map is not a collection.
HashMap<K,V>, Hashtable<K,V> and
LinkedHashMap<K,V> are some implementations.
SortedMap<K,V> extends the Map interface for maps that
maintain their mappings sorted in key order. Implementations
include TreeMap<K, V>.
NavigableMap<K,V> extends and replaces the SortedMap
interface for sorted maps. Implementations include
TreeMap<K, V>.
46. Collection Interface
Basic operations are used to query a collection about its contents
and allow elements to be added to and removed from a
collection.
Basic Operations
int size()
boolean isEmpty()
boolean contains(Object element)
boolean add(E element) Optional
boolean remove(Object element) Optional
Array Operations allow the collections to be converted to array.
Object[] toArray(): Returns array of type Object.
<T> T[] toArray(T[] a): Returns array of type T.
47. Collection and Iterator Interfaces
Bulk operations methods performed on collection as single unit
boolean containsAll(Collection<?> c)
boolean addAll(Collection<? extends E> c) Optional
boolean removeAll(Collection<?> c) Optional
boolean retainAll(Collection<?> c) Optional
void clear() Optional
A collection provides an Iterator which allows sequential access to the
elements of a collection. It is obtained by calling the method of the
Collection interface Iterator<E> iterator() returning the object
implementing Iterator interface.
The generic interface Iterator has the methods:
boolean hasNext(): Returns true if the underlying collection still has
elements left to return.
E next() : moves iterator to next element and returns current element.
void remove() Optional : Removes the element that was returned by
the last call to the next().
When an iterator has already been obtained, structurally modifying the
underlying collection by other means will invalidate the iterator.
48. Enhanced for loop
for (type variable : expression) statement
It sets the given type variable to each element of the
collection and then executes the statement.
The value of expression can be a reference value that
refers to a collection, an array or an object of a class
that implements the java.lang.Iterable interface.
The loop variable of the “for each” loop traverses the
elements of the array, not the index values.
49. Sets
Implementations of the Set interface do not allow duplicate
elements.
Its add() and addAll() methods doesn’t store duplicates.
A HashSet does not guarantee any ordering of the elements
while, the LinkedHashSet subclass of HashSet guarantees
insertion-order.
The SortedSet interface extends the Set interface to provide
the functionality for handling sorted sets.
The NavigableSet interface extends the SortedSet interface
with navigation (searching) methods to find the closest
matches for specific search targets.
50. SortedSet<E> Interface Methods
// First-last elements
E first(): gets first element in the sorted set.
E last(): gets last element in the sorted set.
// Range-view operations
SortedSet<E> headSet(<E> toElement): returns a view of a
portion of sorted set, whose elements are strictly less than the
specified element.
SortedSet<E> tailSet(<E> fromElement) returns a view of a
portion of sorted set, whose elements are strictly greater than the
specified element.
SortedSet<E> subSet(<E> fromElement, <E> toElement):
returns a view of the portion of this sorted set, whose elements
range from fromElement, inclusive, to toElement, exclusive
51. NavigableSet<E> Interface Methods
// First-last elements
E pollFirst(): removes and returns first element.
E pollLast() : removes and returns last element.
// Range-view operations
NavigableSet<E> headSet(<E> toElement, boolean inclusive)
NavigableSet<E> tailSet(<E> fromElement, boolean inclusive)
NavigableSet<E> subSet(<E> fromElement, boolean fromInclusive, <E>
toElement, boolean toInclusive)
// Closest-matches
E ceiling(E e): returns the least element in the navigable set.
E floor(E e): returns the greatest element in the navigable set.
E higher(E e): returns the least element strictly greater than argument.
E lower(E e) : returns the greatest element strictly less than argument.
// Reverse order
Iterator<E> descendingIterator()
NavigableSet<E> descendingSet()
52. Lists
Lists are collections that maintain their elements in order and can contain
duplicates.
// Positional Index
E get(int index): returns element at the specified index.
E set(int index, E element) : replaces the element at the specified index with
the specified element returning the previous element at the specified index.
// Insert or Delete
void add(int index, E element) Optional
boolean addAll(int index, Collection<? extends E> c)
remove(int index) Optional : deletes and returns the element at the specified
index.
// Element Search
int indexOf(Object o): returns the index of the first occurrence of element.
int lastIndexOf(Object o): returns index of the last occurrence of element.
// Open Range-View
List<E> subList(int fromIndex, int toIndex): returns a view of the list, which
consists of the sublist of elements from the index fromIndex to index toIndex-1.
// List Iterators
ListIterator<E> listIterator() and ListIterator<E> listIterator(int index)
53. ArrayList<E>, LinkedList<E>, Vector<E>
The Vector and ArrayList classes are implemented using
dynamically resizable arrays, providing fast random access and
fast list traversal.
The Vector class is thread-safe, meaning that concurrent calls to
the vector will not compromise its integrity.
The LinkedList implementation uses a doubly-linked list and,
Insertions and deletions are very efficient.
Vectors suffer a slight performance penalty due to
synchronization.
Position-based access has constant-time performance for the
ArrayList and Vectors but is in linear time for a LinkedList.
If frequent insertions and deletions occur inside a list, a
LinkedList can be more efficient.
LinkedList class also implements two other interfaces that allow
it to be used for stacks and different kinds of queues.
54. The Queue<E> Interface
A queue is a collection that maintains elements in processing
order.
A head position in the queue specifies where the next element
for processing can be obtained.
Queue interface has the following methods:
// Insert
boolean add(E element): insert the specified element.
boolean offer(E element): no exception if queue full.
// Remove
E poll(): retrieve the head element and remove it
E remove(): queue is empty, the poll() method returns null, but
the remove() method throws a NoSuchElementException.
// Examine
E peek(): retrieve the head element but do not remove it.
E element():If the queue is empty, the peek() method returns
null, but element() method throws NoSuchElementException.
55. PriorityQueue<E> and LinkedList<E>
PriorityQueue is implementation for a queue with priority
ordering.
The implementation is based on a priority heap, a treelike
structure that yields an element at the head of the queue
according to the priority ordering, which is defined either
by the natural ordering of its elements or by a comparator.
In the case of several elements having the same priority,
one of them is chosen arbitrarily.
Elements of a PriorityQueue are not sorted.
The queue only guarantees that elements can be removed
in priority order, and any traversal using an iterator does
not guarantee to abide by the priority order.
56. The Deque<E> Interface
he Deque interface extends the Queue interface to allow double-
ended queues.
It allows operations not just at its head, but also at its tail.
It is a linear unbounded structure in which elements can be
inserted at or removed from either end.
The Deque interface defines symmetrical operations at its head
and tail such as offerFirst() and offerLast().
The ArrayDeque class provides better performance than the
LinkedList class for implementing FIFO queues, and is a better
choice than java.util.Stack class for implementing stacks.
An ArrayDeque is also Iterable, and traversal is always from the
head to the tail while descendingIterator() method for iterating
in reverse order.
57. Maps
A Map defines mappings from keys to values.
The <key, value> pair is called an entry.
A map does not allow duplicate keys and each key
maps to one value at the most, implementing a single-
valued map.
Both the keys and the values must be objects.
The Map interface does not extend the Collection
interface.
The Map interface specifies some optional methods.
58. Map interface basic methods
Object put(K key, V value) Optional : inserts the <key,
value> entry into the map.
Object get(Object key): returns the value to which the
specified key is mapped,
Object remove(Object key) Optional: deletes the entry
for the specified key returning value of the key.
boolean containsKey(Object key): returns true if the
specified key is mapped to a value in the map.
boolean containsValue(Object value): returns true if
exists one or more keys that are mapped to specified value.
int size(): return the number of entries (unique keys).
boolean isEmpty(): whether the map is empty or not.
59. Maps: Bulk and View Operations
void putAll(Map<? extends K, ? extends V> map) Optional: copies
all entries from the specified map to the current map
void clear() Optional: deletes all entries from the current map.
Following methods return a set view of keys, a collection view of values,
and a set view of <key, value> entries, respectively.
1) Set<K> keySet()
2) Collection<V> values(): (does not return a Set)
3) Set<Map, Entry<K, V>> entrySet()
An entry in the entry set view can be manipulated by methods defined
in the interface, which are selfexplanatory:
interface Entry<K, V> {
K getKey();
V getValue();
V setValue(V value);
}
60. HashMap<K,V>, LinkedHashMap<K,V> and
Hashtable<K,V>
The classes HashMap and Hashtable implement unordered
maps.
The class Linked-HashMap implements ordered maps.
The class TreeMap implements sorted maps.
While the HashMap class is not thread-safe and permits one null
key, the Hashtable class is thread-safe and permits non-null keys
and values only.
The LinkedHashMap implementation is a subclass of the
HashMap class.
The elements in a LinkedHashSet are in (element) insertion
order and also maintains its elements in (element) access order.
Adding, removing, and finding entries in a LinkedHashMap can
be slightly slower than in a HashMap.
61. SortedMap<K,V>, NavigableMap<K,V> Interfaces
and TreeMap<K,V> Class
SortedMap interface extends the Map interface to provide
the functionality for implementing maps with sorted key.
Operations of SortedMap interface include get First-last
keys and range views such as headMap(),tailMap() and
subMap().
NavigableMap interface extends the SortedMap interface
with navigation methods to find the closest matches for
specific search targets.
Treemap class provides an implementation that sorts its
entries in a specific order by implementing NavigableMap
interface.
By default in the Treemap class, operations on sorted maps
rely on the natural ordering of the keys while a total
ordering can be specified by passing a customized
comparator to the constructor.
62. Operations on Collections
Ordering Elements in Lists
<E extends Comparable<? super E>> void sort(List<E> list)
<E> void sort(List<E> list, Comparator<? super E> c)
<E> Comparator<E> reverseOrder()
<E> Comparator<E> reverseOrder(Comparator<E>
comparator)
void reverse(List<?> list)
void rotate(List<?> list, int distance)
void shuffle(List<?> list)
void swap(List<?> list, int i, int j)
63. Searching and Changing Elements
in Collections
Searching in Collections
<E> int binarySearch(List<? extends Comparable<? super E>> list, E
key)
<E> int binarySearch(List<? extends E> list, E key,
Comparator<? super E> c))
int indexOfSubList(List<?> source, List<?> target)
int lastIndexOfSubList(List<?> source, List<?> target)
Changing Elements in Collections
<E> boolean addAll(Collection<? super E> collection, E... elements)
<E> void copy(List<? super E> destination, List<? extends E> source)
<E> void fill(List<? super E> list, E element)
<E> boolean replaceAll(List<E> list, E oldVal, E newVal)
<E> List<E> nCopies(int n, E element)
64. Sorting and Searching Arrays
Sorting Arrays
void sort(type[] array)
void sort(type[] array, int fromIndex, int toIndex)
<E> void sort(E[] array, Comparator<? super E> comp)
<E> void sort(E[] array, int fromIndex, int toIndex,
Comparator<? super E> comp)
Searching in Arrays
int binarySearch(type[] array, type key)
int binarySearch(type[] array, int fromIndex, int toIndex, type
key)
<E> int binarySearch(E[] array, E key, Comparator<? super E>
c)
<E> int binarySearch(E[] array, int fromIndex, int toIndex, E
key,
Comparator<? super E> c)
65. Creating List Views and
Miscellaneous Utilities
Creating List Views of Arrays
<E> List<E> asList(E... elements)
Miscellaneous Utility Methods in the Arrays Class
void fill(type[] a, type val)
void fill(type[] a, int fromIndex, int toIndex, type val)
String toString(type[] a)
String deepToString(Object[] a)
66. Collections /
Maps
Interface Duplicates Ordered/ Sorted Methods called on
elements
Data Structure
Implemented
HashSet<E> Set<E> Unique
elements
No order equals()
hashCode()
Hash table, linked
list
LinkedHash
Set<E>
Set<E> Unique
elements
Insertion
order
equals()
hashCode()
Hash table
DoublyLinkList
TreeSet<E> SortedSet<E>,
NavigableSet<E>
Unique
elements
Sorted compareTo() Balanced tree
ArrayList<E> List<E> Allowed Insertion order equals() Resizable array
LinkedList<E> List<E>
Queue<E>
Deque<E>
Allowed Insertion/priority/
Deque order
equals()
compareTo()
Linked list
Vector<E> List<E> Allowed Insertion order equals() Resizable array
Priority-
Queue<E>
Queue<E> Allowed Access according
to priority order
compareTo() Priority heap
ArrayDeque<E> Queue<E>
Deque<E>
Allowed Access according to
FIFO or LIFO
Processing Order
equals() Resizable array
HashMap<K,v> Map<K,V> Unique
keys
No order equals()
hashCode()
Hash table using
array
LinkedHashMap
<K,V>
Map<K,V> Unique
keys
Key insertion order/
Access order of Entries
equals()
hashCode()
Hash table and
doubly-linked
list
Hashtable<K,V> Map<K,V> Unique
keys
No order equals()
hashCode()
Hash table
TreeMap<K,V> SortedMap<K,V>
NavigableMap<K,V>
Unique
keys
Sorted in key order equals()
compareTo()
Balanced tree