COMP-202: Foundations of Programming Lecture 12: Linked List, and File I/O Sandeep Manjanna, Summer 2015
Announcements Assignment 4 is posted and Due on 29 th of June at 11:30 pm. Course Evaluations due date is 29 th June. Final exams : 26 th of June (2pm to 5pm) @ MAASS 112
This Lecture Linked List File Input / Output Review on Passing References to a Method One step at a time.
Review: ArrayList
Arrays vs. ArrayLists Array Fixed Length ArrayList Variable Length.length.size( ) Can hold both Primitive and Reference types Need to know the size before creating. Does not support Generic type Only Reference types No need to specify size for creating an instance. Supports Generic types
Linked List
Linked Lists Pictorial representation of a Linked list of int values. Linked List Start = Data = 3 Data = 2 Data = 5 Data = 1 Data = 7 Next = Next = Next = Next = Next = null Node Node Node Node Node
Building our Linked List We need to define a class for each element in the list: the Node class The Node class should have: A pointer to some data. We will call it its data. For simplicity, we will hold int numbers in our LinkedList. A pointer to the next element in the list. Unsurprisingly, we will call it next.
Building our Linked List public class Node { private int data; private Node next; // add a constructor here // add getter and setter methods here }
Building our Linked List We need to define a class for doing operations on the list: the LinkedList class. The LinkedList class should have: A pointer to the first element in the list. We will call it start. All the methods with the operations we want to make on the list.
Building our Linked List public class LinkedList { private Node start; // add a constructor here // add Insertion, search and deletion methods here }
Methods for our Linked List Inserting a node at the beginning of the List. Linked List Start = Data = 9 Next = null new Node Data = 3 Data = 2 Data = 5 Data = 1 Data = 7 Next = Next = Next = Next = Next = null Node Node Node Node Node
Methods for our Linked List Inserting a node at the end of the List. Linked List Start = Data = 3 Data = 2 Data = 5 Data = 1 Data = 7 Next = Next = Next = Next = Next = null Node Node Node Node Node Data = 9 Next = null new Node
Methods for our Linked List Inserting a node in the middle of the List (Between 5 and 1). Linked List Start = Data = 9 Next = null new Node Data = 3 Data = 2 Data = 5 Data = 1 Data = 7 Next = Next = Next = Next = Next = null Node Node Node Node Node
Methods for our Linked List Removing a node from the List (Remove node with Data = 5). Linked List Start = Data = 3 Data = 2 Data = 5 Data = 1 Data = 7 Next = Next = Next = Next = Next = null Node Node Node Node Node
Methods for our Linked List Removing a node from the List (Remove node with Data = 5). Linked List Start = Data = 3 Data = 2 Data = 1 Data = 7 Next = Next = Next = Next = null Node Node Node Node
Doubly Linked Lists Pictorial representation of a Doubly Linked list of int values. You will be implementing doubly linked list in Assignment 4. Start = Doubly Linked List End = Data = 3 Data = 2 Data = 5 Data = 1 Data = 7 Next = Next = Next = Next = Next = null Prev = null Prev = Prev = Prev = Prev = Node Node Node Node Node
Linked Lists Advantages over arrays: 1) Dynamic size 2) Ease of insertion/deletion Drawbacks: 1) Random access is not possible. We have to access elements sequentially starting from the first node. So we cannot do binary search with linked lists. 2) Extra memory space for a pointer is required with each element of the list.
File Input and File Output
What are System.in, System.out? One of the remaining mysteries in the code we've been writing all semester System.out.println("Hello, world!"); Scanner sc = new Scanner(System.in);
I/O Streams Sequence of bytes that flow from a source to a destination InputStream get bytes from somewhere e.g., System.in gets bytes from the user (via the keyboard) OutputStream write bytes to somewhere else e.g., System.out, System.err write bytes to screen (after converting them to characters) There are many kinds of streams in java.io
Scanner The job of a Scanner is to read characters from some source, then convert it into a desired data type. Constructor: specify where to read from Scanner sc = new Scanner(System.in); methods like.nextint(),.nextdouble(): actually read the characters and convert to an int or double etc. int num = sc.nextint();
Reading Files Instead of passing System.in to Scanner, we can pass in a file as the source of characters! Option 1 FileReader reader = new FileReader("test.txt"); Scanner sc = new Scanner(reader); Option 2 Scanner sc = new Scanner(new File("test.txt"));
Potential Problems What can go wrong when you are reading a file? Cannot find file. File is corrupted. File is protected. File is in unreadable/unexpected format.
Checked Exceptions Java forces us to write try-catch blocks to handle (some of) these problems, because they're very common. try { Scanner sc = new Scanner(new File("test.txt")); // file reading operations here } catch (FileNotFoundException fnfe) { System.err.println("test.txt cannot be found."); } catch (Exception e) { System.err.println("Exception:" + e.getmessage()); }
How to Read Need to check that there is still text to read: while (sc.hasnextline()) { // do the actual reading here String line = sc.nextline(); }
Try it out!! Open your text editor and create a file with several lines. Now, read it and print it out, but append the line number before each line (and a tab '\t'). e.g., 1 The first line goes here. 2 The second line here. 3 The third line here.
Writing to a Text File Instead of writing to System.out, we write to a file with the PrintWriter class! PrintWriter out = new PrintWriter("output.txt"); out.println("hello, hard drive!"); You need to write a try-catch block for this too. Close the file when you're done: out.close();
Buffered Writers You can improve the speed by using buffered versions of the classes above: Input BufferedReader in = new BufferedReader(new FileReader("foo.in")); // feed in to a Scanner Output PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out"))); // can now call out.print(), out.println()
What is Buffering? Accessing the hard disk is slow, so you want to minimize how often you do it. Buffering means saving the data in an intermediate spot, so that the OS can schedule it to happen when it'd be convenient. results in speed-up
Reading and Writing Objects How do we read and write objects? For example, the Cat class which has the name and age of a Cat?
Let us Try it out!! Copy your Cat class from before into the current folder. Then, write two methods: public static void writecats(cat[] cats, String filename) This method writes an array of cats to the specified file public static Cat[] readcats(string filename) This method reads an array of Cats from the specified file
Other Options Access different points in a file, rather than read it sequentially (random access) Read and write bytes, not characters Read and write objects without having to define our own file format (serialization) If you're interested, have a look at: http://docs.oracle.com/javase/tutorial/essential/io/
Review: Passing Reference Type to Methods
Summary Linked List File I / O