0% found this document useful (0 votes)
133 views27 pages

Java Assignment-4 UNIT-4 Input/Output Stream

This document discusses Java input/output streams, serialization, and JDBC. It describes how Java performs I/O through streams which are linked to a physical layer. There are two types of streams: byte streams for input/output of bytes and character streams for input/output of characters. It provides examples of important stream classes and discusses stream filters. The document also summarizes Java object serialization for writing the state of an object to a byte stream, and describes JDBC for connecting and executing queries with a database in Java.

Uploaded by

Harkirat Singh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
133 views27 pages

Java Assignment-4 UNIT-4 Input/Output Stream

This document discusses Java input/output streams, serialization, and JDBC. It describes how Java performs I/O through streams which are linked to a physical layer. There are two types of streams: byte streams for input/output of bytes and character streams for input/output of characters. It provides examples of important stream classes and discusses stream filters. The document also summarizes Java object serialization for writing the state of an object to a byte stream, and describes JDBC for connecting and executing queries with a database in Java.

Uploaded by

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

JAVA ASSIGNMENT-4

UNIT-4
INPUT/OUTPUT STREAM

Java performs I/O through Streams. A Stream is linked to a physical layer by java


I/O system to make input and output operation in java. In general, a stream means
continuous flow of data. Streams are clean way to deal with input/output without
having every part of your code understand the physical.
Java encapsulates Stream under java.io package. Java defines two types of
streams. They are,

1. Byte Stream : It provides a convenient means for handling input and output
of byte.
2. Character Stream : It provides a convenient means for handling input and
output of characters. Character stream uses Unicode and therefore can be
internationalized.

Java Byte Stream Classes


Byte stream is defined by using two abstract class at the top of hierarchy, they are
InputStream and OutputStream.

These two abstract classes have several concrete classes that handle various
devices such as disk files, network connection etc.
Some important Byte stream classes.

Stream class Description

BufferedInputStream Used for Buffered Input Stream.

BufferedOutputStrea Used for Buffered Output Stream.


m

DataInputStream Contains method for reading java standard datatype

DataOutputStream An output stream that contain method for writing java


standard data type

FileInputStream Input stream that reads from a file

FileOutputStream Output stream that write to a file.

InputStream Abstract class that describe stream input.

OutputStream Abstract class that describe stream output.

PrintStream Output Stream that contain print() and println() method

These classes define several key methods. Two most important are

1. read() : reads byte of data.


2. write() : Writes byte of data.

Java Character Stream Classes


Character stream is also defined by using two abstract class at the top of hierarchy,
they are Reader and Writer.
These two abstract classes have several concrete classes that handle unicode
character.

Some important Charcter stream classes


Stream class Description

BufferedReader Handles buffered input stream.

BufferedWriter Handles buffered output stream.

FileReader Input stream that reads from file.

FileWriter Output stream that writes to file.

InputStreamReader Input stream that translate byte to character

OutputStreamReader Output stream that translate character to byte.

PrintWriter Output Stream that contain print() and println() method.

Reader Abstract class that define character stream input

Writer Abstract class that define character stream output


STREAM FILTERS
Stream filter(Predicate predicate) returns a stream consisting of the elements of
this stream that match the given predicate. This is an intermediate operation. These
operations are always lazy i.e, executing an intermediate operation such as filter()
does not actually perform any filtering, but instead creates a new stream that, when
traversed, contains the elements of the initial stream that match the given predicate.
Syntax :
Stream<T> filter(Predicate<? super T> predicate)

Where, Stream is an interface and T is the


type of the input to the predicate.
The function returns the new stream.
Example 1 : filter() method with operation of filtering out the elements divisible by 5.

// Java code for Stream filter


// (Predicate predicate) to get a stream
// consisting of the elements of this
// stream that match the given predicate.
import java.util.*;
  
class GFG {
  
    // Driver code
    public static void main(String[] args)
    {
  
        // Creating a list of Integers
        List<Integer> list = Arrays.asList(3, 4, 6, 12, 20);
  
        // Using Stream filter(Predicate predicate)
        // to get a stream consisting of the
        // elements that are divisible by 5
        list.stream().filter(num -> num % 5 ==
0).forEach(System.out::println);
    }
}
Output :
20

Print Stream Random Access Files


Java also allows you to access the contents of a file in random order i.e. data items
can be read and written in any order. This is especially useful in direct access
applications such as banking systems, airline reservation systems, Automatic Teller
Machine (ATM) etc. where the desired information must be located immediately.
Random access files (or direct access files) are analogous to arrays, where each
element is accessed directly by means of its index number. Java
provides java.io.RandomAccessFile class that enables you to perform random
access file input and output operations as opposed to sequential file I/O offered
by ByteStream and CharacterStream classes.
When a data file is opened for random read and write access, an internal file pointer
is set at the beginning of the file. When you read or write data to the file, the file
pointer moves forward to the next data item. For example, when reading an in
t value using readlnt() , 4 bytes are read from the file and the file pointer moves 4
bytes ahead from the previous file pointer position.
Similarly, when reading a double value using readDouble () , 8 byte are read from the
file pointer and the file pointer moves 8 bytes ahead from the previous file pointer
position.
import java.io.*;
class RandomFileExample
{
     public static void main(String[] args)
    {
          try
          {
        
              RandomAccessFile file = new RandomAccessFile("std.dat","rw");    
              file.setLength(0);
              for(int i=0;i<50;i++)
                   file.writeInt(i);
                   System.out.println("Length of File After Writing Data is :
"+file.length());
                   file.seek(0);
                   System.out.println("First Number is : "+file.readInt());
                   file.seek(1*4);
                   System.out.println("Second Number is : "+file.readInt());
                   file.writeInt(101);
                   file.seek(file.length());
                   file.writeInt(50);
                   System.out.println("Current Length of File is : "+file.length());
          }
                   catch(Exception e)
                  {
                        e.printStackTrace();
                  }
    }
}
JDBC
JDBC stands for Java Database Connectivity. JDBC is a Java API to connect and execute
the query with the database. It is a part of JavaSE (Java Standard Edition). JDBC API
uses JDBC drivers to connect with the database. There are four types of JDBC drivers:

o JDBC-ODBC Bridge Driver,


o Native Driver,
o Network Protocol Driver, and
o Thin Driver

We have discussed the above four drivers in the next chapter.

We can use JDBC API to access tabular data stored in any relational database. By the
help of JDBC API, we can save, update, delete and fetch data from the database. It is
like Open Database Connectivity (ODBC) provided by Microsoft.

The current version of JDBC is 4.3. It is the stable release since 21st September, 2017.
It is based on the X/Open SQL Call Level Interface. The java.sql package contains
classes and interfaces for JDBC API. A list of popular interfaces of JDBC API are given
below:

o Driver interface
o Connection interface
o Statement interface
o PreparedStatement interface
o CallableStatement interface
o ResultSet interface
o ResultSetMetaData interface
o DatabaseMetaData interface
o RowSet interface
A list of popular classes of JDBC API are given below:

o DriverManager class
o Blob class
o Clob class
o Types class

Why Should We Use JDBC


Before JDBC, ODBC API was the database API to connect and execute the query with the
database. But, ODBC API uses ODBC driver which is written in C language (i.e. platform
dependent and unsecured). That is why Java has defined its own API (JDBC API) that
uses JDBC drivers (written in Java language).

We can use JDBC API to handle database using Java program and can perform the
following activities:

1. Connect to the database


2. Execute queries and update statements to the database
3. Retrieve the result received from the database.

JAVA OBJECT SERIALIZATION


Serialization in Java is a mechanism of writing the state of an object
into a byte-stream. It is mainly used in Hibernate, RMI, JPA, EJB and
JMS technologies.

The reverse operation of serialization is called deserialization where


byte-stream is converted into an object. The serialization and
deserialization process is platform-independent, it means you can
serialize an object in a platform and deserialize in different platform.

For serializing the object, we call


the writeObject() method ObjectOutputStream, and for
deserialization we call the readObject() method
of ObjectInputStream class.

We must have to implement the Serializable interface for serializing


the object.

Advantages of Java Serialization

It is mainly used to travel object's state on the network (which is


known as marshaling).
Example of Java Serialization

In this example, we are going to serialize the object of Student class.


The writeObject() method of ObjectOutputStream class provides the
functionality to serialize the object. We are saving the state of the
object in the file named f.txt.

1. import java.io.*;  
2. class Persist{  
3.  public static void main(String args[]){  
4.   try{  
5.   //Creating the object  
6.   Student s1 =new Student(211,"ravi");  
7.   //Creating stream and writing the object  
8.   FileOutputStream fout=new FileOutputStream("f.txt");  
9.   ObjectOutputStream out=new ObjectOutputStream(fout);  
10.   out.writeObject(s1);  
11.   out.flush();  
12.   //closing the stream  
13.   out.close();  
14.   System.out.println("success");  
15.   }catch(Exception e){System.out.println(e);}  
16.  }  
17. }  
SOCKETS
Normally, a server runs on a specific computer and has a socket that is bound to a
specific port number. The server just waits, listening to the socket for a client to
make a connection request.

On the client-side: The client knows the hostname of the machine on which the
server is running and the port number on which the server is listening. To make a
connection request, the client tries to rendezvous with the server on the server's
machine and port. The client also needs to identify itself to the server so it binds to a
local port number that it will use during this connection. This is usually assigned by
the system.

If everything goes well, the server accepts the connection. Upon acceptance, the
server gets a new socket bound to the same local port and also has its remote
endpoint set to the address and port of the client. It needs a new socket so that it can
continue to listen to the original socket for connection requests while tending to the
needs of the connected client.

On the client side, if the connection is accepted, a socket is successfully created and
the client can use the socket to communicate with the server.

The client and server can now communicate by writing to or reading from their
sockets.

Definition: 

A socket is one endpoint of a two-way communication link between two programs


running on the network. A socket is bound to a port number so that the TCP layer
can identify the application that data is destined to be sent to.

An endpoint is a combination of an IP address and a port number. Every TCP


connection can be uniquely identified by its two endpoints. That way you can have
multiple connections between your host and the server.
The java.net package in the Java platform provides a class, Socket, that implements
one side of a two-way connection between your Java program and another program
on the network. The Socket class sits on top of a platform-dependent implementation,
hiding the details of any particular system from your Java program. By using
the java.net.Socket class instead of relying on native code, your Java programs can
communicate over the network in a platform-independent fashion.

Additionally, java.net includes the ServerSocket class, which implements a socket that


servers can use to listen for and accept connections to clients. This lesson shows
you how to use the Socket and ServerSocket classes.

If you are trying to connect to the Web, the URL class and related classes
(URLConnection, URLEncoder) are probably more appropriate than the socket
classes. In fact, URLs are a relatively high-level connection to the Web and use
sockets as part of the underlying implementation. See Working with URLs for
information about connecting to the Web via URLs.

DEVELOPMENT OF CLIENT SERVER APPLICATIONS


A client/server application model typically is viewed as a remotely located, high powered
computing device that stores a large quantity of data with business logic to access them in a
network. The user interface is handled by the client software on a relatively cheap machine.
This idea is not distinct because any machine serving the request can potentially be called a
server. Although the server waits for the client to start a conversation, in some cases the
same program may act as both client and server. In that sense, a single machine can act as
a network providing the communication between the client and the server program that goes
through layers of a TCP/IP protocol stack. A socket is an API provided by the OS to realize
the connection. The package java.net provides the necessary ingredients to implement the
socket communication between two of the topmost TCP/IP layers: application and transport.
The article elaborates the concept behind the client/server model with hands-on details in
creating a TCP client/server application in Java.

Client Socket Basics


A socket establishes the connecting endpoints between two hosts. The Socket class
provided by Java is used for both clients and servers. The basic operations area is as
follows:

 Connect to remote host.


 Send and receive data.
 Close a connection.
 Bind to a port.
 Listen to incoming data.
 Accept remote connections on the bounded port.
The last three operations are specific to servers only; they are implemented by
the ServerSocket class. The client program work flow occurs in the following manner:

1. Create a new socket object.


2. Attempt to connect to the remote host
3. Once connection has succeeded, the local and remote hosts get hold of the input
and output streams and can work in full duplex mode. The data received and sent
can mean different things, depending on the protocol used (data sent/received from
an FTP server can be different from an HTTP server). Generally, there is some kind
of agreement established followed by data transmission.
4. Sockets must be closed at both ends after transmission is completed. Some
protocols, such as HTTP, make sure that the connection is closed upon each request
service. FTP, on the other hands, allows multiple requests to process before closing
the connection.

MULTITHREADED SERVER IN JAVA

Multithreading in java is a process of executing multiple


threads simultaneously. A multi-threaded program contains two or
more process that can run concurrently and each process can handle a
different task at the same time making optimal use of the available
resources specially when your computer has multiple CPUs. The
process of executing multiple threads simultaneously is known
as multithreading .

Multithreaded Socket Programming in Java

In the previous example we already saw how a Single Thread Socket


Program is running. In that case there is only one client can
communicate with the server. It will not allow simultaneous client
connections. Try to start another client. You will see that the second
client cannot be connected until the first client closes its connection.
To allow simultaneous connections we should know multithreaded
programming. Here in the following Multithreaded Socket
Programming , you can connect more than one client connect to the
server and communicate.

How it works?

For each client connection, the server starts a child thread to process
the request independent of any other incoming requests.

The ServerClientThread is a new class extends Thread Class . Here


you can see, rather than processing the incoming requests in the
same thread that accepts the client connection, the connection is
handed off to a client thread that processes the request. That way
the thread listening for next incoming requests spends as much time
as possible in the serverSocket.accept() call. That way the risk is
minimized for clients being denied access to the server because the
listening thread is not inside the accept() call. Here the client thread
actually executes the request. In the meantime server can take
multiple client requests and start the processing. So individual
threads will be started and they will work in parallel . In this example
the client send a number to the server and in response to each client,
the server send back the square of the received number.

REMOTE METHOD INVOCATION


The central concept in the Java remote object implementation is the remote method
invocation or RMI. Code on the client computer invokes a method on an object on the
server. To do so, it actually calls a regular Java method that is encapsulated in a surrogate
object called a stub that resides on the client only. The stub takes the parameters used in
the remote method and packages them up as a block of bytes. This packaging uses a device-
independent encoding for each parameter e.g. numbers are always sent in bigendian
format. The process of encoding the parameters into a format that is suitable for
transporting them across the net is called parameter marshalling. The stub method builds
an information block and then sends this information to the server. On the server side,
there is a skeleton object that makes sense out of the information contained in the packet
and passes that information to the actual object executing the remote method. It then
captures the return value or exception of the call on the method, marshals that value and
sends it back to the stub. The stub unmarshals the return value or exception from the
server. This becomes the return value of the remote method call. Or, if the remote method
threw an exception, the stub re-throws it in the process space of the caller. This process is
largely transparent for the programmer. Also, remote objects look and feel the same as
local objects. The syntax for a remote call is the same as for a local call.

Thus, for example, a client seeking product information can query a warehouse object on
the server. It calls a remote method find which has one parameter, the request form object.
The find method returns an object to the client, the product information object. This can be
depicted as follows:

Invoking a remote method on a server object [4]


Parameter
Request form

find Warehouse

Product Info Server


Client result

The purpose behind RMI is to make all the implementation details transparent to the
programmer so that remote objects and methods work just like the local objects and
methods.

JAVA NATIVE INTERFACES


The Java Native Interface (JNI) is a foreign function interface programming
framework that enables Java code running in a Java virtual machine (JVM) to
call and be called by[1] native applications (programs specific to a hardware
and operating system platform) and libraries written in other languages such
as C, C++ and assembly.
JNI enables programmers to write native methods to handle situations when
an application cannot be written entirely in the Java programming language,
e.g. when the standard Java class library does not support the platform-
specific features or program library. It is also used to modify an existing
application (written in another programming language) to be accessible to
Java applications. Many of the standard library classes depend on JNI to
provide functionality to the developer and the user, e.g. file I/O and sound
capabilities. Including performance- and platform-sensitive API
implementations in the standard library allows all Java applications to access
this functionality in a safe and platform-independent manner.
The JNI framework lets a native method use Java objects in the same way
that Java code uses these objects. A native method can create Java objects
and then inspect and use these objects to perform its tasks. A native method
can also inspect and use objects created by Java application code.
Only applications and signed applets can invoke JNI.
An application that relies on JNI loses the platform portability Java offers (a
partial workaround is to write a separate implementation of JNI code for each
platform and have Java detect the operating system and load the correct one
at runtime).
Not only can native code interface with Java, it can also draw on a
Java  Canvas , which is possible with the Java AWT Native Interface. The
process is almost the same, with just a few changes. The Java AWT Native
Interface is only available since J2SE 1.3.
JNI also allows direct access to assembly code, without even going through
a C bridge.[2] Accessing Java applications from assembly is also possible in
the same way.[3]

Design
In the JNI framework, native functions are implemented in separate .c or .cpp
files. (C++ provides a slightly simpler interface with JNI.) When the JVM
invokes the function, it passes a  JNIEnv  pointer, a  jobject  pointer, and
any Java arguments declared by the Java method. For example, the following
converts a Java string to a native string:

extern "C"
JNIEXPORT void JNICALL Java_ClassName_MethodName
(JNIEnv *env, jobject obj, jstring javaString)
{
const char *nativeString = env-
>GetStringUTFChars(javaString, 0);

//Do something with the nativeString

env->ReleaseStringUTFChars(javaString, nativeString);
}

DEVELOPMENT OF A JNI BASED APPLICATION

A Simple JNI Application


When writing a JNI application for the first time, the main hurdle one will face is that
of the overwhelming steps involved in compiling the code. Following is a very
rudimentary application; the highlight is not on the code but on the steps involved. If
you can compile and run the application, you have crossed a major hurdle. The rest
that remains is grasping the concepts involved, which we'll focus on in the next set of
articles. Stay tuned.

The steps shown herein are the simplest way to write a JNI app disregarding
standard/good programming technique. Make sure you have a GNU g++ compiler
installed for C/C++, along with latest JDK. Also, make sure you can compile C/C++
source code from a command line/terminal, along with Java. This can be
accomplished by setting up bin folder for both Java and C/C++ compiler in the PATH
environment variable.
1. Write the Java Code
To keep it simple, create a folder and name it, say, JNI_project. We shall use it as a parent folder for
every file we create. Now, create a Java file with the following code:

public class JNITest {


static{
System.load("/home/user1/
JNI_project/mynativelib.so");
//System.load("C:\\JNI_project
//\\mynativelib.dll");
}
public native void greet();
public static void main(String[] args) {
JNITest test=new JNITest();
test.greet();
}
}

2. Compile the Java Code


Compiling a Java program that uses JNI is the same as compiling a normal Java code. This will
create a JNITest.class file:

javac JNITest.java

3. Create the C/C++ Header File


The C/C++ header file can be created with the javah tool provided with the JDK. It is automatically
created by the tool. Make sure not to change anything in this header file:

javah JNITest

Or, you can give the package a name with classpath:

javah -cp C:\JNI_project <your package name>.JNITest.java

The generated header file is as follows:

/* DO NOT EDIT THIS FILE - it is machine generated */


#include <jni.h>
/* Header for class JNITest */
#ifndef _Included_JNITest
#define _Included_JNITest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JNITest
* Method: greet
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_JNITest_greet (JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif

4. Write the C/C++ Program


This is a simple C/C++ code. The header file jni.h  is located in the include directory of JDK. Create
the C/C++ file with the name jnitest.cpp:

#include<stdio.h>
#include<jni.h>
#include "JNITest.h"
JNIEXPORT void JNICALL Java_JNITest_greet
(JNIEnv *env, jobject obj){
printf("\n...Welcome to the world of JNI...\n");
return;
}

5. Create a Shared Library


Now, to compile the C/C++ code and create shared libraries, do as follows:

For Windows:

C:\> g++ -Wl,--kill-at -shared -IC:/JDK/include


-IC:/JDK/include/win32 -IC:/dll
-o C:/JNI_project/mynativelib.dll
C:/JNI_project/jnitest.cpp
6. Run the JNI Empowered Java Code
Now, to run the application, type the following command from the command line/terminal:

Windows command line:

java -Djava.library.path=C:\JNI_project JNITest

The Java Collections API


Collections are used for storing groups of objects. The Collections API
provides a number of interfaces (including Collection, List, Map and Set) to
define a standard way of using a range of concrete data structures. The
interfaces and classes of the Collections API belong to
the java.util package.

Commonly used classes and interfaces of Java's Collection


framework

Collection Characteristics

Characteristics of collections include:

 Ordered. It is possible to iterate over the elements of an ordered


collection in a predictable order.
 Uniqueness of elements. Some collections do not allow duplicate
elements. Objects are considered as duplicates if, according to
their equals(Object) methods, they are equal.
 Array-based storage. Some collections use an array internally to
store their elements. The array is resized to accommodate more
elements. Array storage is generally fast to access but slow to
remove or insert elements.
 Linked-list storage. In linked-lists each element is stored in another
object that has a reference to the next and (in a double-linked list)
previous element. Linked-lists are efficient at removing or inserting
elements but slower for access.
 Hash-based storage. Hash-based storage generates identifying keys
for the elements it stores. In Java, hash-based collections use
the Object.hashCode() method to generate the identifying keys. Hash-
based storage can provide reasonably efficient access and growth
but its effectiveness relies on the hashCode() method of the elements it
stores to, as much as possible, return different values for different
objects. If a hash-based collection stores objects of a class
whose hashCode() method always returns the same value then the
collection will actually function more like an array-based collection but
with the additional overhead of calculating the hash values.
 Tree-based storage. A tree requires a way of ordering the elements it
stores. A tree is efficient for searching.

VECTORS
Java Vector class comes under the java.util package. The vector class
implements a growable array of objects. Like an array, it contains the
component that can be accessed using an integer index.

Vector is very useful if we don't know the size of an array in advance or we need
one that can change the size over the lifetime of a program.

Vector implements a dynamic array that means it can grow or shrink as


required. It is similar to the ArrayList, but with two differences-

o Vector is synchronized.
o The vector contains many legacy methods that are not the part of a
collections framework

Java Vector Class Declaration

1. public class Vector<E>  
2. extends Object<E>  
3. implements List<E>, Cloneable, Serializable  

Java Vector Class Constructors


Vector class supports four types of constructors. These are:

SN Constructor Description

1 vector() It constructs an empty vector with the default size as


) 10.

2 vector(int initialCapacity) It constructs an empty vector with the specified initial


) capacity and with its capacity increment equal to
zero.

3 vector(int initialCapacity, int It constructs an empty vector with the specified initial
) capacityIncrement) capacity and capacity increment.

4 Vector( Collection<? extends It constructs a vector that contains the elements of a


) E> c) collection c.

STACKS

A Stack is a Last In First Out (LIFO) data structure. It supports two


basic operations called push and pop. The  push  operation adds an
element at the top of the stack, and the  pop  operation removes an
element from the top of the stack.
Java provides a Stack class which models the Stack data structure.
The Stack class is part of Java’s collections framework. Following is
the class hierarchy of Stack in Java -

The Stack class extends  Vector  which implements


the  List  interface. A Vector is a re-sizable collection. It grows its size
to accommodate new elements and shrinks the size when the
elements are removed.
Since the Stack class extends  Vector , it also grows and shrinks its
size as needed when new elements are added or removed.

Hashtable Class

Hashtable class implements Map interface. Hashtable stores the data in


the form of key-value pairs, where key and value are objects. Hashcode of
each key is computed internally and this value of hash code is used as
an index at which the value is stored in the hash table. This is how the
association between each key-value pair is formed.

Some important features of Hashtable

 Null values cannot be stored in the keys or values.


 Hashtable is very similar to HashMap but Hashtable is
synchronized and thread-safe while HashMap is not synchronized.
 Hashtable elements are ordered on the basis of hashcode value of
each key(which is computed internally) & hence order of key-value
pairs may appear different as compared to their insertion order.

A simple constructor of Hashtable class

Hashtable()

This constructor creates an empty Hashtable.


Example -

Hashtable <Integer,Integer> ht = new Hashtable <Integer,Integer>();

This constructor creates a Stack to hold key-value pair of Integer objects.

Some methods in a Hashtable.

As Hashtable implements Map interface, so some methods are inherited from Map.

Methods Description

void clear() Removes all the key/value pairs from the Hashtable.
Returns the total number of key-value pairs in a
int size()
Hashtable.

boolean isEmpty() Returns true if Hashtable has no key-value pair in it.

V get(Object key) Returns the value associated with a specified key.

Puts the specified key and its associated value in the


put(K key, V value)
Hashtable.

Set<Map.Entry<K,V>>
Returns the Set containing Map.Entry objects.
entrySet()

Java Enumerations
Enumerations was added to Java language in
JDK5. Enumeration means a list of named constant. In Java,
enumeration defines a class type. An Enumeration can have
constructors, methods and instance variables. It is created
using enum keyword. Each enumeration constant
is public, static and final by default. Even though enumeration
defines a class type and have constructors, you do not
instantiate an enum using new. Enumeration variables are
used and declared in much a same way as you do a primitive
variable.

Java Collections -- List Set Map


This document introduces the main features of the java collections framework. The three most
important types are "List", "Set", and "Map". A List is like an array, except it grows and shrinks
automatically as needed. The Set is like the List, but automatically rejects duplicate elements. The
Map is a key/value dictionary that supports the efficient storage and retrieval of information by a
key.

The Collection interface is a general interface that includes sub-interfaces List and Set. If a method
has a parameter of type Collection, such as the addAll(Collection coll) method below, you can
pass it a List or Set and it will work fine. List is an interface, and ArrayList is the typically used class
that implements List. Likewise, Set is an interface, and HashSet is the commonly used class that
implements Set. The Map interface is separate from the Collection interface. The Map interface
defines a key/value lookup dictionary, and HashMap is the most commonly used Map. The sections
below explain all of these classes.

Lists
The List is probably the single most useful and widely used type of Collection. List is a general
interface, and ArrayList and LinkedList are implementing classes. ArrayList is the best general
purpose List, so that's what we'll use here.

A List is a linear structure where each element is known by an index number 0, 1, 2, ... len-1 (like an
array). Lists can only store objects, like String and Integer, but not primitives like int. You cannot
create a List of int, but you can create a list of Integer objects. This is a common feature of all the
Java Collection classes (see boxing below). Another way to say this is that the collection classes can
only store pointers.

Iterator
The foreach syntax -- for (String str: words) ... -- is the easiest way to iterate over a list. "Iterator"
objects provide an alternative and more flexible way to iterate over a list. In fact, behind the scenes,
the foreach syntax just creates an Iterator object to do the iteration.

Iterator objects are generic by the element type, so for a List<String>, you use an Iterator<String>.
Iterators are shown here with lists, but iterators work for all collection types. To use an Iterator, call
the collection's iterator() method which returns an Iterator object, ready to iterate over that
collection:
// Suppose we have a "words" list of strings:
List words = new ArrayList(); // create a list of strings
// Here's how to create an iterator to go through all the words:
Iterator it = words.iterator();

The Iterator object is temporary -- you use it to go through the elements in the list and then discard
it. The Iterator has two main methods:

boolean hasNext() -- returns true if the iterator has more elements.


T next() -- returns the "next" element from the list which will be type T, where T is the generic
type of the list (e.g. String). Only call this if hasNext() returns true.

Use the iterator with a loop like this:


Iterator<String> it =
words.iterator(); while
(it.hasNext()) {
String str = it.next();
// Do something with str
}

Each call to next() yields the next element from the list until there are no more elements, at which
point hasNext() returns false. It is an error to call next() when hasNext() is false. During the
hasNext()/next() iteration, it is not valid to modify the underlying list with add/remove operations.
Code that uses iteration must not modify the collection during the iteration.

Iterator Remove
The Iterator has a remove() method that removes the element from the previous call to next(). It is
not valid to modify the list during iteration generally, but iterator remove() is an allowed exception.
It is only valid to call it.remove() once for each call to it.next(). For example, here is code that iterates
over the words list, removing all the words of length 4 or more:
// words is: {"this", "and",
"that"} // Remove words
length 4 or more.
Iterator<String> it =
words.iterator(); while
(it.hasNext()) {
String str = it.next();
if (str.length() >= 4) it.remove();
}
// words is: {"and"}

Using it.remove() during iteration is potentially a very clean and efficient strategy -- it does not have
to search the whole list for the element, since the element to remove is at the current spot of the
iterator. Contrast this to the more expensive list.remove(Object target) above which must
search the whole list for the target and then remove it.

It's possible to have multiple iterators going over a collection at the same time, each proceeding
through all the elements independently. In that case, no add/remove modifications to the collection
are allowed -- it would be too complicated for the multiple iterators to coordinate their changes.

The above code demonstrates the basic Iterator class which works for all collection types, including
lists. There is a more powerful type of iterator, the ListIterator, which works for list types, but not
other collection types. The ListIterator can go forwards and backwards and can insert and delete.
The ListIterator is powerful but more rarely used -- you can get quite far with the plain foreach for
common loops, and the Iterator when you want to delete during iteration. Iterators are not
restricted to the Collection classes -- any class that implements the Iterable interface to provide an
Iterator object with hasNext(), next(), etc. can support iteration just like the collection classes.
Sets
The Java "Set" is a Collection, like the List, but with the added constraint that each element can be in
the Set once, using equals() to test if two elements are the same. If an add() operation tries to add
an element that is already in the set, the add() is silently ignored. This can be useful to store values
where you want this sort of mathematical set behavior. The standard Collection methods --
contains(), addAll(), iterator()... -- work for Sets as they do for any Collection. With Sets, the standard
utility methods addAll(), retainAll(), containsAll() now give you fully functioning mathematical set
operations. To make a set union of x and y, call x.addAll(y). To make the intersection of sets x and y,
call x.retainAll(y). To test if x is a subset of y, call y.containsAll(x). Sets do not impose a 0..size-1
indexing of the elements (that's what Lists do), so List methods like get(int index) are not available
for sets. Sets are potentially more efficient than lists. In particular, the HashSet can find or insert an
element in constant time.
// Create a Set of Integer objects
Set<Integer> nums = new HashSet<Integer>();

// Add the
numbers 1..10 for
(int i=1; i<=10; i++) {
nums.add(i);
}

// Add 1, 4, 9, 16, 25
// Since it's a Set, only the add() of 16 and 25
do anything. for (int i=1; i<=5; i++) {
nums.add(i * i);
}

// Foreach works on a Set.


for (int num:nums) {
System.out.println(num);
}
//
Iterator works on a set.
// (the values will appear in some random order for a HashSet
// as we have here)
Iterator<Integer> it =
nums.iterator(); while
(it.hasNext()) { int
val = it.next();
}

// Other Collection utilties work


nums.contains(9); // true
nums.containsAll(Arrays.asList(1, 2, 3)); //
true // addAll() is essentially a
mathematical union operation.
// Change nums to the union with the set {16, 17}
nums.addAll(Arrays.asList(16, 17));

// Accessing by index number DOES NOT work


// (index numbers are List feature only)
// int val2 = nums.get(0); //NO does not compile
The HashSet is the most commonly used, as shown above. HashSet only works with elements, like
String and Integer, which have a hashCode() defined. The TreeSet is an alternative which is a little
more costly, but keeps the set in sorted order, so iteration will yield the values in sorted order.

Map
A Map is very different from List and Set. A Map is a key/value table that can look up any entry by
key very efficiently (know as a "hash table" or "dictionary").

"Map" is a general interface of the basic map features, implemented by two main classes: HashMap
and TreeMap. HashMap is by far the more commonly used one, and that's what we will us here.

A Map stores key/value entries, where each key in the map is associated with a single value. For
example, here is a map where the each key is the string name of a city and the associated value is
the lat/long location of that city (in this case, both key and value are strings):

Most uses of a map involve just two methods put() and get():
put(Object key, Object value) -- puts an entry for the given key into the map with
the given value. If there was an existing value for that key, it is overwritten by this new
value. Object get(Object key) -- gets the value previously stored for this key, or null
if there is no entry for this key in the map.
boolean containsKey(Object key) -- returns true if the map contains an entry for
the given key. int size() -- returns the number of key/value entries in the map

With Java version 5, the Map is most often used with generics to indicate the type of key and
the type of value. Both the key and value must be object types such as String or Integer or List. For
example, below is code that creates a new HashMap where both the key and value are Strings.
"Map" is the general interface for maps, and "HashMap" is the particular type of map created here.
It is standard to declare the variable with the general type, Map, as shown here:
Map<String, String> states = new HashMap<String, String>();

states.put("ca", "California");
states.put("az", "Arizona");
states.put("mn", "Minnesota");
states.put("nj", "New Jersey");

Once a value is put in the map with put(), it can be retrieved with get():
states.get("ca") // returns "California"
states.get("nj") // returns "New Jersey"
states.get("xx") // returns null, there is no entry for "xx"

states.put("nj", "Garden State"); // Put a new entry for "nj", overwriting the old
entry states.get("nj") // returns "Garden State"
For a HashMap, the keys are stored in a seemingly random order. The important feature of get() and
put() is that they are fast. With a HashMap, even if there are a 100,000 entries in the map, get() and
put() can access a particular entry almost instantaneously (constant time). This very fast
performance is a feature of HashMap; the TreeMap is slower. That's why everyone uses HashMap.
For whatever problem you are solving, if there is part of the problem that involves storing
information under some key and retrieving that information later ... use a HashMap. The HashMap is
simple to use, reliable, and fast.

You might also like