Java Interfaces
A Java Interface allows you to specify methods that must be implemented by a class
- Simply speaking, it is just a list of methods, but no implementations (up to Java 7)
- Several interfaces:
List<E>
Map<K, V>
Set<E>
Comparable<T> (- compareTo() method defines natural ordering of Type)
Comparator<T> (- compare() method defines alternative ordering of Type)
Abstraction
"The essence of abstractions is preserving information that is relevant in a given context, and forgetting information that is irrelevant in that context."
Use whenever suitable in order to avoid duplication in code
In a class hierarchy, higher classes are more general/abstract
- Think of it as a basis for other classes than as a class with specific instances you want to use
A class in the middle of class hierarchy (declared abstract)
public abstract class Person { ... }
Incomplete
- Has methods & variables common to its subclasses
- Can have concrete methods
- Put common fields and methods in superclass
- Some methods can be abstract (specification only)
public abstract String getDescription();
Must be subclassed (to be instantiated)
- You cannot say "new" on an abstract class
Abstract Class vs. Interface
Abstract Class | Interface | |
Concrete Class | "extends" Single inheritance | "implements" Can implement multiple interfaces |
Variables | No restrictions Can have both instance and static fields | All variables must be public static final |
Constructors | Abstract class cannot be instantiated using the new operator | No constructors An interface cannot be instantiated using the new operator |
Methods | No restrictions Can have public protected, private concrete methods | All methods must be public |
File I/O
Files can be classified as Text or Binary
- file that can be (meant to be) processed using a text editor is text file
- All the other files called binary files (Designed to be read by a program)
Java source code files (*.java) are text files
Java class files (*.class) are binary files
Abstract Classes for I/O
In the java.io package
The Reader & Writer classes
- Abstract Classes
- Let you read & write characters (text)
The InputStream & OutputStream classes
- Abstract Classes
- Let you read & write bytes (binary)
Binary I/O
InputStream
- Abstract read() method - Read one byte and return it or -1 if it encounters the end of the input source
OutputStream
- Abstract write() method - Write one byte to an output location
Concrete methods to read & write an array of bytes
Character I/O
Reader class to read
- Abstract class
- Concrete read() method
Return a single character's unicode code unit (between 0 and 65535) or -1 when reached the end of the file
Writer class to write
- Abstract class
- Concrete write(int c) method
Argument c is the unicode code unit just like the read method
Text I/O
Mainly focus on using two concrete classes (FileReader and BufferedReader)
FileReader class
- New constructors
- No additional methods
BufferedReader class
- New constructors
- Override Reader class's read() method
- readLine() method which lets you read a line of text or "null" when no more line is available
Typical way to read a file:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ReadLineTest {
/**
* Simple test program to print lines of a file using BufferedReader.
* @param args arguments
*/
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Program to print out lines of a file, in typical fashion:");
System.out.println("using BufferedReader");
System.out.println("doing it one line at a time (with readLine())");
System.out.println("not worrying about unprintable characters");
System.out.println("put line numbers in front of each printed line");
System.out.println(" Usage: java ReadLineTest filename");
return;
}
try {
BufferedReader br = new BufferedReader(new FileReader(args[0]));
int lineNumber = 0;
boolean eof = false;
while (!eof) {
String line = br.readLine();
if (line == null) {
eof = true;
} else {
lineNumber = lineNumber + 1;
System.out.println("line " + lineNumber + ": " + line);
}
}
br.close();
} catch (FileNotFoundException e) {
System.out.println("File " + args[0] + " was not found");
return;
} catch (IOException e) {
System.out.println();
System.out.println(e);
return;
}
}
}
The Beauty of Buffers
Not using buffers would be like shopping without a cart
- Buffers are like shopping car to put items till it is full
- Then, you make fewer trips (if not one trip) to your car
Use Buffered I/O!
What Exceptions Must You Catch?
Subclasses of RuntimeException and Error need not be caught or declared as thrown from a method
- NumberFormatException
- ArrayIndexOutOfBounds
- StackOverflowError
Other exceptions must be caught or your method declaration must state that you might throw them
- FileNotFoundException
- IOException
- InterruptedException
Subclass to Handle Parsing
Can subclass BufferedReader to handle the parsing of the input stream
CSV Parsing Example
Class to read CSV file and return the values separated in an array of Strings
- Extends BufferedReader
- Calls super() in its constructor
- A new readCSVLine() method which calls super.readLine() method
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
/**
* A simplified version of CSV Reader.
*
* Subclass of a BufferedReader to handle a character stream that consists of
* comma separated values (CSVs)
*
* Provides an additional instance method, readCSVLine(), that parses lines into
* substrings. The substrings are separated by comma in the original input
* stream. The readCSVLine() method returns an array of references to Strings.
* The Strings are the values from the line that were separated by commas. If a
* value was surrounded by quotes, the quotes are removed.
*
* Limitations: Spaces before or after the commas are not removed. In the first
* and last quote are removed from a value. Embedding commas in a quoted value
* is not handled properly. (In this case, the commas will separate the values
* and the quotes will not be removed from the ends of those values.
*/
public class CSVReader extends BufferedReader {
/**
* Initializes the class.
* @param in the reader from which to read CSV lines
*/
public CSVReader(Reader in) {
super(in);
}
/**
* This is the only additional method. It uses readLine from the superclass
* to get a line but returns the comma separated values as in an array of
* strings.
* @return an array of Strings containing the values At the end of the file,
* readCSVLine returns null (just as readLine does).
* @throws IOException throws IOException
*/
public String[] readCSVLine() throws IOException {
// Get a line by calling the superclass's readLine method
String line = super.readLine();
// If we're at the end of the file, readLine returns null
// so we return null.
if (line == null) {
return null;
}
// Count up the number of commas
int commaCount = 0;
for (int i = 0; i < line.length(); i++) {
if (line.charAt(i) == ',') {
commaCount = commaCount + 1;
}
}
// Allocate an array of the necessary size to return the strings
String[] values = new String[commaCount + 1];
// In a loop, set beginIndex and endIndex to the start and end
// positions of each argment and then use the substring method
// to create strings for each of the comma separate values
// Start beginIndex at the beginning of the String, position 0
int beginIndex = 0;
for (int i = 0; i < commaCount; i++) {
// set endIndex to the position of the (next) comma
int endIndex = line.indexOf(',', beginIndex);
// if the argument begins and ends with quotes, remove them
if (line.charAt(beginIndex) == '"' && line.charAt(endIndex - 1) == '"') {
// If we made it here, we have quotes around our string.
// Add/substract one from the start/end of the args
// to substring to get the value. (See else comment
// below for details on how this works.)
values[i] = line.substring(beginIndex + 1, endIndex - 1);
} else {
// If we name it here, we don't have quotes around
// our string. Take the substring of this line
// from the beginIndex to the endIndex. The substring
// method called on a String will return the portion
// of the String starting with the beginIndex and up
// to but not including the endIndex.
values[i] = line.substring(beginIndex, endIndex);
}
// Set beginIndex to the position character after the
// comma. (Remember, endIndex was set to the position
// of the comma.)
beginIndex = endIndex + 1;
}
// handle the value that's after the last comma
if (line.charAt(beginIndex) == '"' && line.charAt(line.length() - 1) == '"') {
values[commaCount] = line.substring(beginIndex + 1, line.length() - 1);
} else {
values[commaCount] = line.substring(beginIndex, line.length());
}
return values;
}
}
And a Test Program to test CSVReader
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class CSVReaderTest {
/**
* Simple test program to read CSV files.
* @param args arguments
*/
public static void main(String[] args) throws FileNotFoundException, IOException {
if (args.length != 1) {
System.out.println("Usage: java CSVReaderTest <filename>");
System.exit(0);
}
FileReader fr = new FileReader(args[0]);
CSVReader c = new CSVReader(fr);
int lineNum = 0;
boolean eof = false;
while (!eof) {
String[] values = c.readCSVLine();
if (values == null) {
eof = true;
} else {
lineNum = lineNum + 1;
System.out.print("Line " + lineNum + " " + values.length + " components:");
for (int i = 0; i < values.length; i++) {
System.out.print(" \"" + values[i] + "\"");
}
System.out.println();
}
}
c.close();
}
}
Binary I/O and Dealing with Files (before Java 7)
java.io.File class
- Represents a file on a disk but does not represent the contents
- Thus, does NOT have methods to read and write
- Provide useful methods to manipulate files and directories such as getName(), getPath(), delete(), exists(), etc
- Useful to verify a valid path and file
Just like BufferedReader
- Use BufferedInputStream to read
- Use BufferedOutputStream to write
(After Java 7)
java.nio.file package
- Path Interface: Locate a file on a file system
- Paths Class: Two static methods to return Path from string and URI
- Files Class: All static methods that operate on files and directories such as create, copy, move, delete, etc
IP Addresses
A unique number of each network address on the Internet
IPv4
- The 2nd generation of IP addresses
- A four byte IP address, ~ a billion addresses, not all available
- Running out of them
IPv6
- The 3rd generation of IP addresses
- A sixteen byte IP address, literally zillions of addresses
Ports
Computer has a small number of IP address (typically: wired, wireless, localhost)
Each application on computer can use one or more port numbers to cause network traffic to be routed to it
IP Address is like a mall, and Port number is like a store in the mall
How to read from the network (Client)
Use the java.net.Socket class with host and port
Socket client = new Socket(host, port);
Clients bind, connect and then get the InputStream and OutputStream
client.getInputStream();
client.getOutputStream();
Use DataInputStream and DataOutputStream
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF( ... )
DataInputStream class is to read bytes from a binary stream and reconstructing from the data in any of the Java primitive types and String
DataOutputStream class is to convert data from any of the Java primitive types and String to a series of bytes and writing these bytes to a binary stream
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class SimpleClient {
/**
* Simple test program to read and write as a client over the network.
* @param args arguments
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
Socket client = new Socket(args[0], 9898);
OutputStream os = client.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(args[1]);
dos.flush();
InputStream is = client.getInputStream();
DataInputStream dis = new DataInputStream(is);
String str = new String(dis.readUTF());
System.out.println("Received from " + client.getInetAddress() + ": " + str);
client.close();
}
}
How to read from the network (server)
Use java.net.ServerSocket with port and java.net.Socket classes
ServerSocket server = new ServerSocket(port);
Socket client = server.accept();
Servers bind and accept, then get the InputStream and OutputStream
client.getInputStream();
client.getOutputStream();
Use DataInputStream and DataOutputStream
DataInputStream dis = new DataInputStream(is);
String str = dis.readUTF();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("Thank you: " + client.getInetAddress());
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SimpleServer {
/**
* Simple test program to read and write as a server over the network.
* @param args arguments
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
ServerSocket ss = new ServerSocket(9898);
System.out.println("Server is up and listening...");
System.out.println();
Socket client = ss.accept();
System.out.println("Connection from " + client.getInetAddress());
// InputStream to read bytes
InputStream is = client.getInputStream();
DataInputStream dis = new DataInputStream(is);
String str = new String(dis.readUTF());
System.out.println(" Received: " + str);
// OutputStream to write bytes
OutputStream os = client.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("Thank you: " + client.getInetAddress());
System.out.println();
System.out.println("Good bye!!! Server is down.");
// don't forget to close resources
dos.close();
dis.close();
client.close();
ss.close();
}
}
HTTP
This is just a socket protocol
- Runs on port 80 by default
- Send HTTP requests (GET, POST, etc)
- Receive HTTP reply (Header, Data)
How to read from the web in Java?
Use java.net.URL
- Get an InputStream,
- Get an InputStreamReader
- Get a BufferedReader
- Read it like a file
Don't forget to close everything when done
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
public class URLToStringTest {
/**
* Maximum size constant.
*/
private static final int MAX_SIZE = 4 * 1024 * 1024;
/**
* Reads the response from a url and returns its string representation.
* @param urlString url to parse
* @return String representation of the response from a url
*/
private static String urlToString(String urlString) {
try {
URL url = new URL(urlString);
InputStream is = url.openStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
StringBuilder b = new StringBuilder();
boolean eof = false;
while (!eof && b.length() < MAX_SIZE) {
String line = br.readLine();
if (line == null) {
eof = true;
} else {
b.append(line);
b.append('\n');
}
}
br.close();
return b.toString();
} catch (IOException e) {
throw new AssertionError(e);
}
}
/**
* Simple test program to read and print from a url.
* @param args arguments
*/
public static void main(String[] args) {
System.out.println(urlToString(args[0]));
}
}