JAVA Lists and Files. Objectives Be able to use ArrayLists: Create Initialize Add elements Retrieve...

Post on 29-Dec-2015

232 views 1 download

Tags:

Transcript of JAVA Lists and Files. Objectives Be able to use ArrayLists: Create Initialize Add elements Retrieve...

JAVALists 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;• 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

Some hint goes here (maybe an image and/or text)…

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 array

0

7

ArrayLists: Adding Values (add) ArrayLists handle their own memory allocation.

List<aType> aList = new ArrayList<aType>();aList.add(aTypeObject);

aList [0] [1] … [m-1]

size array

1

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 [0] [1] … [m-1]

aTypeObject

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

m+1

aTypeObject

[0] [1] … [m-1][m] …

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 slidepublic 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 SyntaxString[] 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

+getHintText()+guess()+reset()

Country

+myName+myContinent

CountryGuessTest

*1

16

ArrayLists can be passed as parameters.

ArrayLists: 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 can be returned as return values.

ArrayLists: 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: CopyingList<Country> original = new ArrayList<Country>();// add two country objects to original (c1 & c2)…List<Country> referenceCopy = original;

List<Country> shallowCopy = (List<Country>)original.clone();

original size array

2

c1 c2

referenceCopy

shallowCopy size array

2

19

List<Country> deepCopy = deepCopy(original);

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;}

deepCopy size array

2

c1copy c2Copy

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.

Multi-dimensional List Structures

• Multi-dimensional lists are useful for more general multi-dimensional structures.

• Example:

22

Text

+title: String Paragraph

Sentence

Word

+value: String

0..*1

0..*

1

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.

User’s guess… Give up

Some hint goes here (maybe an image and/or audio)…

24

Example: Design• The design includes the following classes:

CharacterDrillController

CharacterDrill

+myAnswerIndex+myHintCount

+guess()+reset()+getHintImageFilename()+getHintPronunciationFilename()+getHintText()

Character

+myTranslation+myPinyin+myImageFilename+myPronunciationFilename+mySentenceCharacterDrillTest

*1

CharacterPanel

+setImage()+setPronunciation()

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:

Program

Input Stream

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.

import java.io.File;import java.io.FileNotFoundException;import java.util.ArrayList;import java.util.List;import 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 ...}

Statistics Solution Structure

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 InputProblem: Read in soldier data from a file. Soldiers may

or may not have nickname(s).

Given: the data filename and pathAlgorithm:

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.

ReadRecordsConsole

Soldier

+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 OutputProblem: Get data from the user, put it into a file.

Given: the output filename and pathAlgorithm:

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 ImplementationPrintWriter 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

CharacterDrillController

CharacterDrill

+myAnswerIndex+myHintCount

+guess()+reset()+getHintImageFilename()+getHintPronunciationFilename()+getHintText()

Character

+myTranslation+myPinyin+myImageFilename+myPronunciationFilename+mySentenceCharacterDrillTest

*1

CharacterPanel

+setImage()+setPronunciation()