12listsFilesx

Download Report

Transcript 12listsFilesx

JAVA
Lists and Files
Objectives
• Be able to use ArrayLists:
• Create
• Initialize
• Add elements
• Retrieve elements
• Pass as arguments to methods
• Return from methods
• Be able to use Random to get a random number
• Be able to parse input from a file
• Be able to write output to a file
3
Example: Analysis and Design
• We’d like to make a guessing
game that drills students on the
countries of the world.
• Elements:
• A GUI controller;
Some hint goes here
(maybe an image
and/or text)…
• A Game class that:
• Represents a list of countries;
• Randomly chooses a country as the
current answer;
• Produces a sequence of hints.
• A Country class that:
• Represents stuff about countries.
Your guess…
Give up
4
Limitations of Arrays
• Our initial iteration assumes that:
• We know how many countries there are;
• We’re happy with the low-level array methods.
• Moving beyond these assumptions forces us to give up
arrays because arrays:
• Are fixed in size at compile time;
• Have a limited set of predefined methods.
5
Lists
• Java’s List data structure is more flexible:
• Lists can grow or shrink at run time.
• Lists provide more predefined behaviors.
• The Java Collections framework provides classes supporting
groups of objects:
• List<> specifies an
interface for an ordered collection of typed
objects;
• ArrayList<> implements the List<> interface using an array.
6
The ArrayList Class
ArrayLists store an array of typed objects.
List<aType> aList = new ArrayList<aType>();
aList
size
0
array
7
ArrayLists: Adding Values (add)
ArrayLists handle their own memory allocation.
List<aType> aList = new ArrayList<aType>();
aList.add(aTypeObject);
size
array
1
[0] [1] … [m-1]
aList
aTypeObject
8
ArrayLists: Accessing Values (get)
ArrayLists provide indexed access.
List<aType> aList = new ArrayList<aType>();
aList.add(aTypeObject);
System.out.println(aList.get(arrayIndex));
aList
size
array
1
aTypeObject
[0] [1] … [m-1]
9
ArrayLists: Memory Allocation
ArrayLists allocate memory automatically.
List<aType> aList = new ArrayList<aType>();
aList.add(aTypeObject);
System.out.println(aList.get(arrayIndex));
aList.add(a2ndTypeObject);
...
aList.add(anM+1stTypeObject);
aList
size
array
[0] [1] … [m-1][m] …
m+1
aTypeObject
a2ndTypeObject
anM+1stTypeObject
Random
• To get a random number in Java, create a random number
generator:
Random randomGenerator = new Random();
• The generator will return a new random number each time it is
asked to do so:
int randomNumber1 = randomGenerator.nextInt();
int randomNumber2 = randomGenerator.nextInt(15);
double randNumber3 =
randomGenerator.nextDouble();
Using lists for our example
• We’d like to have an arbitrary number of countries in
the “list”.
• We’ll keep the same GUI controller, but will create an
arbitrarily long List of country name Strings.
• Upgrade the CountryGuessGame to use lists rather
than arrays. The results of this programming should be
as follows:
• CountryGuessController1 should not change;
• CountryGuessGame should end up looking like
CountryGuessGame1 (handout).
package c12lists.lecture.countryguess;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class CountryGuessGame {
private List<String> myCountries;
private int myAnswerIndex, myHintCount;
private Random myRandom;
public CountryGuessGame() {
myCountries = new ArrayList<String>();
myCountries.add("Honduras");
myCountries.add("Panama");
myRandom = new Random();
reset();
}
public void reset() {
myAnswerIndex = myRandom.nextInt(myCountries.size());
myHintCount = 0;
} //continued on next slide
//continued from previous slide
public boolean guess(String text) {
return myCountries.get(myAnswerIndex).equalsIgnoreCase(text);
}
public String getAnswer() {
return myCountries.get(myAnswerIndex);
}
public String getHintText() {
myHintCount++;
String name = myCountries.get(myAnswerIndex);
if (myHintCount == 1) {
return "The name starts with '" + name.charAt(0) + "'";
} else if (myHintCount == 2) {
return "The name has " + name.length() + " letters";
} else if (myHintCount == 3) {
return "The name ends with '" +
name.charAt(name.length() - 1) + "'";
} else {
return "no more hints";
}
}
} //ends CountryGuessGame class
14
Array & Lists Syntax
String[] myCountries = new String[2];
myCountries[0] = "Honduras";
myCountries[1] = "Panama";
System.out.println(myCountriesArray.length);
System.out.println(myCountriesArray[0]);
List<String> myCountriesList = new ArrayList<String>();
myCountriesList.add("Honduras");
myCountriesList.add("Panama");
System.out.println(myCountriesList.size());
System.out.println(myCountriesList.get(0));
15
Modeling Countries
CountryGuessController
CountryGuessGame
+myAnswerIndex
+myHintCount
CountryGuessTest
+getHintText()
+guess()
+reset()
Country
1
*
+myName
+myContinent
16
ArrayLists: As Parameters
ArrayLists can be passed as parameters.
private int count(List<Country> countries, String continent) {
int result = 0;
for (int i = 0; i < countries.size(); i++) {
if (countries.get(i).getContinentName()
.equalsIgnoreCase(continent)) {
result++;
}
}
return result;
}
17
ArrayLists: As Return values
ArrayLists can be returned as return values.
private List<Country> loadCountries() {
List<Country> result = new ArrayList<Country>();
result.add(new Country("Algeria", "Africa"));
result.add(new Country("Angola", "Africa"));
...
return result;
}
18
ArrayList: Copying
List<Country> original = new ArrayList<Country>();
// add two country objects to original (c1 & c2)…
List<Country> referenceCopy = original;
original
size
array
2
referenceCopy
c1
c2
List<Country> shallowCopy = (List<Country>)original.clone();
shallowCopy
size
2
array
19
List<Country> deepCopy = deepCopy(original);
deepCopy
size
array
2
c1copy
c2Copy
public List<Country> deepCopy(List<Country> original) {
List<Country> result = new ArrayList<Country>();
for (int i = 0; i < original.size(); i++)
result.add(new Country(myCountries.get(i).getName(),
myCountries.get(i).getContinentName(),
myCountries.get(i).getImageName()));
return result;
}
20
ArrayList Equality
Similar issues arise when checking arraylist equality:
• anArrayList.equals(anotherArrayList) checks the two
lists are the same size and that their corresponding elements
are equals().
• This works for lists of strings, but special equality checking
routines must be written for lists of other types.
• The String class has an equals() operator that checks string
equality properly.
21
Multi-Dimensional Lists
• Lists can also be multi-dimensional.
• Declaring 2-D lists:
ArrayList<ArrayList<RType>> ID
• Initializing 2-D lists:
new ArrayList<ArrayList<RType>>(rowsize)
• Accessing 2-D array elements:
ID.get(row).get(column)
• Multidimensional arrays are generally easier to use and
more efficient.
22
Multi-dimensional List Structures
• Multi-dimensional lists are useful for more general multi-
dimensional structures.
• Example:
Text
+title: String
1
0..*
Paragraph
1
0..*
Sentence
Word
+value: String
0..*
1
23
Example: Character Drill
• We’d like to modify the guessing
game so that drills students on
Chinese Characters.
• A sketch of a solution
achieving this goal is shown here.
Some hint goes here
(maybe an image
and/or audio)…
User’s guess…
Give up
24
Example: Design
• The design includes the following classes:
CharacterPanel
CharacterDrillController
+setImage()
+setPronunciation()
CharacterDrill
+myAnswerIndex
+myHintCount
CharacterDrillTest
+guess()
+reset()
+getHintImageFilename()
+getHintPronunciationFilename()
+getHintText()
Character
1
*
+myTranslation
+myPinyin
+myImageFilename
+myPronunciationFilename
+mySentence
25
Limitations of Hard-Coding Data
• Our initial iteration assumes that:
• we can code the data directly in the program;
• the data never (or rarely) changes;
• people who change data know how to program.
• This approach does not scale well to real data-based
applications.
26
Input & Output Streams
• Input and output in Java is accomplished using stream
classes:
Input Stream
Program
Output Stream
Program
27
Java Streams
• Simple I/O uses predefined streams:
• System.in
• System.out
• System.err
• Create file streams using:
• File
• Scanner
• PrintWriter
28
File
• The File class models a system-independent view of a file
comprising:
• Filename;
• Directory pathname:
• Relative;
• Absolute.
• Patterns:
new File(pathAndFilenameString)
new File(pathnameString, filenameString)
29
Scanner
• The Scanner class can scan:
• Keyboard input stream;
• File;
• String.
• Pattern:
new Scanner(inputStreamOrFileOrString)
• The API includes these methods:
• next() nextInt() nextLine() ...
• hasNext() hasNextInt() hasNextLine() ...
• close()
Example: Compute Statistics
Problem: Compute statistics for a file of quiz scores.
Given: the data filename and path
Algorithm:
• Open a read stream/scanner to the given file.
• While the file has more tokens:
• Read the token.
• Process the token.
• Close the file stream/scanner.
Statistics Solution Structure
import
import
import
import
import
java.io.File;
java.io.FileNotFoundException;
java.util.ArrayList;
java.util.List;
java.util.Scanner;
public class Statistics {
public static final String PATH = “src/c11files/examples/data/”;
//main method will go here ...
//compute methods will go here ...
}
Method implementations on next slides
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Data filename: ");
String filename = keyboard.next();
try{
Scanner fileIn = new Scanner(new File(PATH, filename));
List<Integer> scores = new ArrayList<Integer>();
while (fileIn.hasNext()) {
scores.add(fileIn.nextInt());
}
fileIn.close();
System.out.println(scores);
double average = computeAverage(scores);
System.out.printf("average: %5.2f%n", average);
System.out.printf("std dev: %5.2f%n",
computeVariance(scores, average));
}
catch(FileNotFoundException e){
System.out.println("Invalid file indicated.");
}
}
public static double computeVariance(
List<Integer> values, double average)
throws Exception {
if (values == null || values.size() == 0) {
throw new Exception("Empty list");
}
int sum = 0;
for (int i = 0; i < values.size(); i++) {
sum += Math.pow(values.get(i) - average, 2);
}
return Math.sqrt(sum / values.size());
}
34
public static double computeAverage(List<Integer> values)
throws Exception {
if (values == null || values.size() == 0) {
throw new Exception("Empty list");
}
int sum = 0;
for (int i = 0; i < values.size(); i++){
sum += values.get(i);
}
return sum / values.size();
}
35
Example: Record Input
Problem: Read in soldier data from a file. Soldiers may
or may not have nickname(s).
Given: the data filename and path
Algorithm:
Open a read stream/scanner to the given file.
While the file has more lines:
Read the line.
Process the fixed and variant tokens.
Close the file stream/scanner.
Soldier
ReadRecordsConsole
+myName
+myRank
+mySerialNumber
+myNicknames
+Soldier(String)
+toString()
public class ReadRecordsConsole {
public static final String PATH = "src/c11files/examples/data/";
public static void main(String[] args) {
try{
Scanner keyboard = new Scanner(System.in);
System.out.print("Data Records filename: ");
String filename = keyboard.next();
Scanner fileIn = new Scanner(new File(PATH, filename));
List<Soldier> soldiers = new ArrayList<Soldier>();
while (fileIn.hasNextLine()) {
soldiers.add(new Soldier(fileIn.nextLine()));
}
fileIn.close();
for (int i = 0; i < soldiers.size(); i++) {
System.out.println(soldiers.get(i));
}
}
catch(FileNotFoundException e){
System.out.println("Invalid File indicated.");
}
}
}
public class Soldier {
private String myName, myRank, mySerialNumber;
private List<String> myNickNames;
public Soldier(String line) {
Scanner scanner = new Scanner(line);
myName = scanner.next();
myRank = scanner.next();
mySerialNumber = scanner.next();
myNickNames = new ArrayList<String>();
while (scanner.hasNext()) {
myNickNames.add(scanner.next());
}
scanner.close();
}
public String toString() {
String result = myName + " " + myRank + " " +
mySerialNumber;
for (int i = 0; i < myNickNames.size(); i++) {
result += " " + myNickNames.get(i);
}
return result;
}
}
38
PrintWriter
• The PrintWriter class can print formatted text to a
text-output stream.
• Pattern:
new PrintWriter(outputFile)
• The API includes these methods:
• print() println() ...
• printf()
• close() flush()
39
Example: File Output
Problem: Get data from the user, put it into a file.
Given: the output filename and path
Algorithm:
Open a print writer stream to the given file.
Loop forever:
Prompt for and read a line of data.
If the line is the sentinel
Quit.
else
Output the line.
Close the file stream/scanner.
40
Example Implementation
PrintWriter fileOut = new PrintWriter(new File(path, filename));
String line = "";
while (true) {
System.out.print("enter record (just enter to quit): ");
line = keyboard.nextLine();
if (line.equals("")) {
break;
} else {
fileOut.println(line);
}
}
fileOut.close();
System.out.println("data stored to: " + path + filename);
Character Drill Revisited
CharacterPanel
CharacterDrillController
+setImage()
+setPronunciation()
CharacterDrill
+myAnswerIndex
+myHintCount
CharacterDrillTest
+guess()
+reset()
+getHintImageFilename()
+getHintPronunciationFilename()
+getHintText()
Character
1
*
+myTranslation
+myPinyin
+myImageFilename
+myPronunciationFilename
+mySentence