I am struggling to read this stack trace exception below. I wonder If you could help me?
I don't understand any of the numbers in the code (like the number 74, 2119 and 2160, what do they represent in this exception? Quite literally, I need to know which line of my code is causing problems so that I can resolve it. Please help.
Here below is my stack trace, and beneath it is the java code I am trying to resolve alongside a sample input file which came with the task.
java.util.InputMismatchException
in java.util.Scanner.throwFor(Scanner.java:909)
in java.util.Scanner.next(Scanner.java:1530)
in java.util.Scanner.nextInt(Scanner.java:2160)
in java.util.Scanner.nextInt(Scanner.java:2119)
in League.loadLeague(League.java:74)
in (Workspace:1)
And here, below is my Java code with the method loadLeague which is causing me a lot of headache!
import java.io.*;
import java.util.*;
/**
* Class League - An instance of this class represents the teams in a
* football (or similar) league. It provides a class method for creating
* a new instance of League by reading the data for the teams from a CSV
* file.
*
* #author Lewis Jones
* #version 1.0
*/
public class League
{
/* instance variables */
private String name; // The name of the league
private Team[] teams; // An array to hold the teams in the league
/**
* Constructor for objects of class League. It sets the name of the league
* to the String object provided as the first argument and initialises teams
* to an array of the size provided as the second argument. This constructor
* is private as it is intended for use only by the class method loadLeague().
*/
private League(String aName, int size)
{
super();
this.name = aName;
this.teams = new Team[size];
}
/* class method */
/**
* This method creates a new League object by reading the required details from
* a CSV file. The file must be organised as follows:
* name(String), number of teams (int)
* team name(String), won(int), drawn(int), lost(int), for(int), against (int)
* and so on for each team
* Having created the new League object the method should create all the Team
* objects (using the data in the file to set their attributes) and add them
* to the teams array.
*/
public static League loadLeague()
{
League theLeague = null;
String pathname = OUFileChooser.getFilename();
File aFile = new File(pathname);
Scanner bufferedScanner = null;
try
{
String leagueName;
int numberOfTeams;
String teamName;
int won;
int drawn;
int lost;
int goalsFor;
int goalsAgainst;
Scanner lineScanner;
String currentLine;
bufferedScanner = new Scanner(new BufferedReader(new FileReader (aFile)));
while (bufferedScanner.hasNextLine())
{
currentLine = bufferedScanner.nextLine();
lineScanner = new Scanner(currentLine);
lineScanner.useDelimiter(",");
leagueName = bufferedScanner.next();
numberOfTeams = bufferedScanner.nextInt();
teamName = bufferedScanner.next();
won = lineScanner.nextInt();
drawn = lineScanner.nextInt();
lost = lineScanner.nextInt();
goalsFor = lineScanner.nextInt();
goalsAgainst = lineScanner.nextInt();
Team aTeam = new Team(lineScanner.next());
aTeam.setWon(lineScanner.nextInt());
aTeam.setDrawn(lineScanner.nextInt());
aTeam.setLost(lineScanner.nextInt());
aTeam.setGoalsFor(lineScanner.nextInt());
aTeam.setGoalsAgainst(lineScanner.nextInt());
Team[] teams = new Team[numberOfTeams];
teams[numberOfTeams] = aTeam;
numberOfTeams++;
theLeague = new League(leagueName, numberOfTeams);
}
}
catch (Exception anException)
{
System.out.println("Error: " + anException);
}
finally
{
try
{
bufferedScanner.close();
}
catch (Exception anException)
{
System.out.println("Error: " + anException);
}
}
return theLeague;
}
/* instance methods */
/**
* Displays the league table in tabular format to the standard output
*/
public void display()
{
System.out.println(this.name);
System.out.format("%20s %2s %2s %2s %2s %2s %2s % 2s\n","","P","W","L","D","F","A","Pt");
for (Team eachTeam : this.teams)
{
System.out.format("%20s %2d %2d %2d %2d %2d %2d %2d\n",
eachTeam.getName(), eachTeam.getPlayed(),
eachTeam.getWon(), eachTeam.getDrawn(),
eachTeam.getLost(),eachTeam.getGoalsFor(),
eachTeam.getGoalsAgainst(), eachTeam.getPoints());
}
}
/**
* Arrange the elements of teams in their natural order. This will only
* work if a natural order has been defined for the class Team.
*/
public void sort()
{
// to be written later...
}
}
And below is the sample (file) input which the program is supposed to read into:
Scottish League Division 1,10
Airdrie United ,3,2,11,14,25
Clyde ,5,7,4,21,17
Dundee ,7,2,7,21,18
Gretna ,10,3,3,43,20
Hamilton Acas ,7,5,4,19,20
Livingstone ,6,6,4,21,15
Partick Thistle,8,4,4,25,29
Queen of South ,3,3,10,11,31
Ross County ,4,4,8,14,24
St Johnstone ,6,6,4,26,16
I have really struggled with this task for nearly a week now! I hope someone out there comes to my rescue as it's really getting on my skin now. Please help. Any tips to pinpoint which code I'm writing wrongly would be so much appreciated.
Thank you guys,
Lew.
Those numbers (74, 2119 and 2160) are the code lines. The top most line of the stack trace is where the actual error occurred, and the rest are the call locations in the stack trace.
So in this event, Scanner.java:909 means that the error occurred at line 909 of the Scanner class, which was in a function called at line 1530 in Scanner, and so on and so forth.
Related
So, I am making an application where I saved details of a client such as first name, surname, DOB, ID and address into a file called "clientListFile.txt". Everytime, a client information is added to the file there is an empty space before and after the information as shown below:
//empty line
//empty line
fn
sn
1900-08-01
1234
addressname
s
8
hn
a
pc
t
country
//empty line
//empty line
fn1
sn1
1900-08-02 ... (etc)
In the code below, I am able to find if a string is stored into the file. For example, in my program, if I search "fn" or if I search "1234", it prints out which line it is located on. However, I want it to print out everything in the JTextArea called "jDisplaySearchedClientsTextArea" between the first two empty lines and the last two empty lines.
private void jSearchClientsButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
String fn = jClientsFNTextField.getText();
String clientListFile = "clientListFile.txt";
try {
BufferedReader areader = new BufferedReader(new FileReader(new File(clientListFile)));
Scanner scanner = new Scanner(clientListFile);
//now read the file line by line...
int lineNum = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
lineNum++;
if (fn.equals(areader.readLine())) {
System.out.println("ho hum, i found it on line " +lineNum);
}
}
}
catch (IOException ioe) {
System.out.println("Error while saving Head Office Address");
}
}
You might use a method something like this:
/**
* Parses and searches a "clientListFile.txt" data file based on the supplied
* search criteria.<br>
*
* #param dataFilePath (String) The full path and file name of the data file
* to search in.<br>
*
* #param searchCriteria (String) What to search for in each data record
* contained within the supplied data file.<br>
*
* #param useContains (Optional - Boolean - Default is True) This optional
* parameter by default is boolean '<b>true</b>'. This means that every search
* done in any data file record is carried out by locating the search criteria
* (ignoring letter case) within any record field value location that <u><b>contains</b></u>
* the search criteria. An example
* of this would be:<pre>
*
* Search Criteria: "fred"
*
* A Data Record:
* =============
* First Name: Danny (No Match)
* Surname: Fredrikson (Match - Fred......)
* Birthdate: 1957-11-07 (No Match)
* Cient ID: 1234 (No Match)
* Address: 3233 Sandy St. (No Match)
* City: Fredericton (Match - Fred.......)
* Province: New Brunswick (No Match)
* etc.....</pre><br>
*
* If boolean '<b>false</b>' is optionally supplied then the search is done
* based on <u><b>equality</b></u>. This means that every search done in any data file
* record is carried out by locating the search criteria within any record
* field value that is <b>equal to</b> (ignoring letter case) the supplied
* search criteria. An example of this would be:<pre>
*
* Search Criteria: "fred"
*
* A Data Record:
* =============
* First Name: Fred (Match - Fred)
* Surname: Fredrikson (No Match)
* Birthdate: 1957-11-07 (No Match)
* Cient ID: 1234 (No Match)
* Address: 3233 Sandy St. (No Match)
* City: Fredericton (No Match)
* Province: New Brunswick (No Match)
* etc.....</pre><br>
*
* #return A List Interface Object of Type String - {#code List<String>}.
*/
public static List<String> searchInRecords(String dataFilePath, String searchCriteria, boolean... useContains) {
boolean UseCONTAINSinSearches = true;
if (useContains.length > 0) {
UseCONTAINSinSearches = useContains[0];
}
int fileLinesCounter = 0;
int fieldsCounter = 0;
int dataRecordsCounter = 0;
int criterialFoundRecords = 0;
boolean inRecord = false;
List<String> foundRecords = new ArrayList<>();
String[] fields = new String[12];
// 'Try With Resources' use here to auto-close the reader.
try (BufferedReader reader = new BufferedReader(new FileReader(dataFilePath))) {
String line;
while ((line = reader.readLine()) != null) {
fileLinesCounter++;
line = line.trim();
if (line.isEmpty() && fieldsCounter == 0) {
inRecord = true;
}
else if (inRecord && fieldsCounter <= 11) {
fields[fieldsCounter] = line;
if (fieldsCounter == 11) {
String record = new StringBuilder("").append(fields[0]).append(", ")
.append(fields[1]).append(", ").append(fields[2]).append(", ")
.append(fields[3]).append(", ").append(fields[4]).append(", ")
.append(fields[5]).append(", ").append(fields[6]).append(", ")
.append(fields[7]).append(", ").append(fields[8]).append(", ")
.append(fields[9]).append(", ").append(fields[10]).append(", ")
.append(fields[11]).toString();
dataRecordsCounter++;
// Search Type 1 (using CONTAINS where criteria is anywhere in a field)
if (UseCONTAINSinSearches) {
for (String field : fields) {
if (field == null) { continue; }
if (field.toLowerCase().contains(searchCriteria)) {
if (!foundRecords.contains(record)) {
foundRecords.add(record);
criterialFoundRecords++;
}
}
}
}
// Search Type 2 (using exact match to field but ignoring letter case)
else {
for (String field : fields) {
if (field == null) { continue; }
if (field.equalsIgnoreCase(searchCriteria)) {
if (!foundRecords.contains(record)) {
foundRecords.add(record);
criterialFoundRecords++;
}
}
}
}
}
fieldsCounter++;
}
else {
fieldsCounter = 0;
inRecord = false;
}
}
}
// Handle the exceptions (if any) any way you see fit.
catch (FileNotFoundException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}
/* The following integer type variables can be used to supply related
class member variables. They serve no specific purpose within this
method and can be removed if desired. Sometimes this information can
be handy. */
System.out.println("Overall Number of Data File Lines: --> " + fileLinesCounter);
System.out.println("Overall Number of Records in File: --> " + dataRecordsCounter);
System.out.println("Criterial Search - Records Found: --> " + criterialFoundRecords);
return foundRecords;
}
Far better of course to utilize a database for this sort of thing and the use of a Client class. Even with a file type data storage method (like you are using), you would really want a Client class to keep that data organized and store the data more like in a CSV style (Comma Separated Values) file. Here is an example of a custom CSV data file:
Client ID, First Name, Sir Name, Date Of Birth, Address, City, State/Province, Postal Code, Country, E-Mail, Phone Number
=======================================================================================================================================================================================
1234, Fred, Flinstone, 1957-11-07, 2977 Oriole Cooky Way, Bedrock, Stones Throw, V2Q5W8, Canada, his-email#yahoo.com, 604-776-1121
1235, Wilma, Flinstone, 1964-11-30, 2977 Oriole Cooky Way, Bedrock, Stones Throw, V2Q5W8, Canada, her-email#yahoo.com, 604-776-3466
1236, Jack, Naso, 1993-03-18, 33912 CrackShack Ave, Vancouver, British Columbia, V2Z1D2, Canada, myemailaddy#hotmail.com, 856-302-1122
1237, William, Shakaconn, 1996-12-13, 1212 Playwrite Street, Langely, British Columbia, V2T4C9, Canada, playme#gmail.ca, 777-664-9351
In this custom CSV file the data is laid out more like a table and records are more legible even when just reading the file itself. If you want your Client class to do this sort of thing then just E-Mail me.
I'm testing this class
/**
* Class to classify irises based on petal and sepal measurements.
*
* #author James Howard <jh#jameshoward.us>
*/
package us.jameshoward.iristypes;
import java.io.InputStream;
import java.util.Dictionary;
import java.util.Enumeration;
import weka.classifiers.Classifier;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.SerializationHelper;
public class Iris {
private Classifier classModel;
private Instances dataModel;
private String classModelFile = "/Irises/etc/iris.model";
/**
* Class constructor.
*/
public Iris() throws Exception {
InputStream classModelStream;
// Create a stream object for the model file embedded
// within the JAR file.
classModelStream = getClass().getResourceAsStream(classModelFile);
classModel = (Classifier)SerializationHelper.read(classModelStream) ;
}
/**
* Close the instance by setting both the model file string and
* the model object itself to null. When the garbage collector
* runs, this should make clean up simpler. However, the garbage
* collector is not called synchronously since that should be
* managed by the larger execution environment.
*/
public void close() {
classModel = null;
classModelFile = null;
}
/**
* Evaluate the model on the data provided by #param measures.
* This returns a string with the species name.
*
* #param measures object with petal and sepal measurements
* #return string with the species name
* #throws Exception
*/
public String classifySpecies(Dictionary<String, String> measures) throws Exception {
#SuppressWarnings("rawtypes")
FastVector dataClasses = new FastVector();
FastVector dataAttribs = new FastVector();
Attribute species;
double values[] = new double[measures.size() + 1];
int i = 0, maxIndex = 0;
// Assemble the potential species options.
dataClasses.addElement("setosa");
dataClasses.addElement("versicolor");
dataClasses.addElement("virginica");
species = new Attribute("species", dataClasses);
// Create the object to classify on.
for (Enumeration<String> keys = measures.keys(); keys.hasMoreElements(); ) {
String key = keys.nextElement();
double val = Double.parseDouble(measures.get(key));
dataAttribs.addElement(new Attribute(key));
values[i++] = val;
}
dataAttribs.addElement(species);
dataModel = new Instances("classify", dataAttribs, 0);
dataModel.setClass(species);
dataModel.add(new Instance(1, values));
dataModel.instance(0).setClassMissing();
// Find the class with the highest estimated likelihood
double cl[] = classModel.distributionForInstance(dataModel.instance(0));
for(i = 0; i < cl.length; i++)
if(cl[i] > cl[maxIndex])
maxIndex = i;
return dataModel.classAttribute().value(maxIndex);
}
}
when start initialising its instance from another class with
Iris irisModel = new Iris();
i got following error
Exception in thread "main" java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:159)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2320)
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2333)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2804)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at weka.core.SerializationHelper.read(SerializationHelper.java:288)
at us.jameshoward.iristypes.Iris.<init>(Iris.java:33)
at us.jameshoward.iristypes.IrisDriver.main(IrisDriver.java:11)
I guess this error is case specific, by comparing with other posts, i still cant find out where it went wrong. in fact, this class was downloaded from IBMknowledge website, it supposes to be error-proof i guess.
anyone knows how to fix this?
thanks
I'm trying to analyze a list of albums from a file.There are 22 albums in my list and one of the items in the list is a duplicate and another is not in correct form.I'm supposed to throw two exceptions and print helpful messages on the console.My InputMismatchException is working fine, although my program should continue reading file inputs skipping the album object/line in the list where the exception occurred.Another exception is a DuplicateAlbumException, which is a custom exception.This exception should ignore the duplicate, print a helpful message on the console that mentions that the duplicate has been ignored , and only read the item one time. The following is my txt file that has inputs of albums:top20albums.txt
Led Zeppelin IV 1971
Led Zeppelin II 1969
Fleetwood Mac Rumors 1977
Pink Floyd The Wall 1979
XXXXX XXXXXXXXX XXXX
The Clash London Calling 1979
The Beatles Abbey Road 1969
Van Morrison Moondance 1971
Talking Heads Fear of Music 1979
Who Who's Next 1971
The Beatles Rubber Soul 1965
Cure Kiss Me, Kiss Me, Kiss Me 1987
Violent Femmes Violent Femmes 1982
Pink Floyd The Wall 1979
Soul Coughing Ruby Vroom 1994
James Laid 1993
Liz Phair Exile in Guyville 1993
Pink Floyd Dark Side of the Moon 1973
Police Zenyatta Mondatta 1980
Led Zeppelin Houses of the Holy 1973
Soul Coughing Irresistable Bliss 1996
Replacements Tim 1985
Expected output:
java AlbumList top20albums.txt
ERROR: Line 5: Invalid input for year. Skipping line
ERROR: Line 14: Duplicate album 'The Wall' by Pink Floyd
Album Rankings from top20albums.txt
Rank Title Artist Year
---- ------------------------------ -------------------- ----
1 IV Led Zeppelin 1971
2 II Led Zeppelin 1969
3 Rumors Fleetwood Mac 1977
4 The Wall Pink Floyd 1979
5 London Calling The Clash 1979
6 Abbey Road The Beatles 1969
7 Moondance Van Morrison 1971
8 Fear of Music Talking Heads 1979
9 Who's Next Who 1971
10 Rubber Soul The Beatles 1965
11 Kiss Me, Kiss Me, Kiss Me Cure 1987
12 Violent Femmes Violent Femmes 1982
13 Ruby Vroom Soul Coughing 1994
14 Laid James 1993
15 Exile in Guyville Liz Phair 1993
16 Dark Side of the Moon Pink Floyd 1973
17 Zenyatta Mondatta Police 1980
18 Houses of the Holy Led Zeppelin 1973
19 Irresistible Bliss Soul Coughing 1996
20 Tim Replacements 1985
My output on the eclipse console:
ERROR: Line 5: Invalid input for year. Skipping line.
Rank Title Artist Year
---- ----- ------ -----
1 IV Led Zeppelin 1971
2 II Led Zeppelin 1969
3 Rumors Fleetwood Mac 1977
4 The Wall Pink Floyd 1979
My effort so far is in the following:
class #1
// -------------------------------------------------------------------------
/**
* This Album class has four data fields; String title,String artist,
* int year, int rank.I will be creating an ArrayList of Album object in another class later
* which I will name as AlbumList.This Album class represents each Album o object in the
* top20albums.txt file, where we have 22 albums.
*
* #author Anonymous
* #version Mar 26, 2016
*/
public class Album
{
private String title;
private String artist;
private int year;
private int rank;
public Album () {
}
public Album(String title,String artist,int year,int rank) {
//this(title,artist,year);
this.title = title;
this.artist = artist;
this.year = year;
this.rank = rank;
}
public Album(String title,String artist,int year) {
this.title=title;
this.artist=artist;
this.year=year;
rank = -1;
}
public String getTitle()
{
return title;
}
public String getArtist()
{
return artist;
}
public int getYear()
{
return year;
}
public int getRank()
{
return rank;
}
public void setRank(int rank)
{
this.rank = rank;
}
/*
* // ----------------------------------------------------------
* overridden boolean method from the Object class which tests if
* two Album objects have the same artist and title or not.Later based on the
* invokation of the method we will throw the custom DuplicateAlbumException
*/
public boolean equals(Object obj) {
if(obj instanceof Album )
return (this.title.equals(((Album)obj).title)) && (this.artist.equals(((Album)obj).artist));
else
return this == obj;
}
public String toString() {
return String.format("%-4d %-30s %-20s %-4d", rank,title,artist,year);
}
}
class #2
import java.util.*;
import java.io.*;
// -------------------------------------------------------------------------
/**
* This AlbumList class will create ArrayList of Album objects, read inputs from the
* top20Albums.txt file and then analyze the album inputs.It will print album inputs
* on the console in neat columns, throw two exceptions; one is expected to occur at
* line 5 because of the type mismatch, another is expected to occur at line 15 because of
* the album duplication.I will later create a custom DuplicateAlbumException class that
* will throw exception when the Scanner reads the duplicate file and print a helpful
* message on the console.
*
* #author Anonymous
* #version Mar 26, 2016
*/
public class AlbumList
{
private List <Album> albums ;
public AlbumList(){
albums = new ArrayList<>();
}
// ----------------------------------------------------------
/**
* This method reads file input and throws exceptions robustly.
* #param inFile
*/
public void ReadAlbumsFromFile(File inFile) {
int count = 0;
int rank = 1;
try {
Scanner input = new Scanner(inFile);
input.useDelimiter("\\t|[\\n\\r\\f]+");
while (input.hasNext()) {
String artist = input.next();
String title = input.next();
int year = input.nextInt();
Album albumObject = new Album(title,artist,year,rank);
addAlbum(albumObject);
count ++;
rank++;
}
}
// This exception will not occur unless I give it a file input that does not exist.
catch (FileNotFoundException exception)
{
System.out.println("The file was not found.");
}
/* This exception works fine.However, the Scanner should continue reading the file
* inputs just skipping the 5th line where the mismatch occur.My program for some reason
* is not printing any more input after skipping the line and that is my problem.
*/
catch (InputMismatchException exception)
{
System.out.println("ERROR: Line "+(count+1)+": Invalid input for year. Skipping line.");
}
catch (DuplicateAlbumException exception)
{
System.out.println(exception.getMessage());
Album object = new Album();
System.out.println("ERROR: Line "+(count+1)+": Duplicate album"+object.getTitle()+" by "+object.getArtist());
}
}
// ----------------------------------------------------------
/**
* This DuplicateAlbumException should work fine if the Scanner keeps reading
* even after the mismatch exception occurs, at least that is what it seems
* to me because we are still unable to read line 15 where we expect the duplicate to occur.
* The custom duplicate exception class was already made.
* #param albumObject
* #throws DuplicateAlbumException
*/
public void addAlbum (Album albumObject) throws DuplicateAlbumException {
for(int i =0; i < albums.size();i++) {
if(albums.get(i).equals(albumObject)) {
throw new DuplicateAlbumException(albumObject.getTitle(),albumObject.getArtist());
}
}
/* Look that I am adding albumObjects after the catch blocks so IT SHOULD
* continue reading file inputs even after the exception occurs but it is not doing
* so.
*/
albums.add(albumObject);
}
public void printAlbums () {
albums.toString();
for (int i = 0; i < albums.size(); i++ )
System.out.println(albums.get(i));
}
public static void main(String [] args) throws Exception {
/*This is a way to write on the console so that the user can
* write the file name on the runtime console.
*/
if (args.length != 1) {
System.out.println("java AlbumList top20albums.txt ");
System.exit(0);
}
AlbumList albumListObject = new AlbumList();
File currentFile = new File(args[0]);
albumListObject.ReadAlbumsFromFile(currentFile) ;
System.out.println("\nRank Title \t\t\t Artist \t\t Year");
System.out.println("---- ----- \t\t\t ------ \t\t -----\n");
albumListObject.printAlbums();
}
}
class #3
// -------------------------------------------------------------------------
/**
* This is my custom exception class.
*
* #author Anonymous
* #version Mar 26, 2016
*/
public class DuplicateAlbumException extends ArrayStoreException
{
public DuplicateAlbumException(String title,
String artist) {
super ("Duplicate album" + title+
"by" + artist);
}
}
I hope my code blocks have enough information and explanation for you to understand my concern.But i would explicitly say it again: Why my Scanner stopped reading file input after the mismatch exception?
The problem is the .nextInt() is throwing the InputMismatchException causing the control to go out of the while loop. Refactor the code to
try {
Scanner input = new Scanner(inFile);
input.useDelimiter("\\t|[\\n\\r\\f]+");
while (input.hasNext()) {
try{
String artist = input.next();
String title = input.next();
int year = input.nextInt();
Album albumObject = new Album(title,artist,year,rank);
addAlbum(albumObject);
count ++;
rank++;
}
catch (InputMismatchException exception)
{
System.out.println("ERROR: Line "+(count+1)+": Invalid input for year. Skipping line.");
}
}
}
// This exception will not occur unless I give it a file input that does not exist.
catch (FileNotFoundException exception)
{
System.out.println("The file was not found.");
}
/* This exception works fine.However, the Scanner should continue reading the file
* inputs just skipping the 5th line where the mismatch occur.My program for some reason
* is not printing any more input after skipping the line and that is my problem.
*/
I hope this solves your problem
First of we are going to use a set, because you do not want duplicate albums.
Second we are going to say each line has an album. The reason to do this is because your Scanner will not advance when there is an input missmatch exception. Then you have another problem, where you scanner is not on the next line.
Set<Album> albums = new HashSet<>();
try(
BufferedReader reader = Files.newBufferedReader(
inFile.toPath(), Charset.forName("UTF8")
)
){
String line;
while((line = reader.readline())!=null){
Scanner input = new Scanner(line);
input.useDelimiter("\\t|[\\n\\r\\f]+");
int rank = 0;
try{
String artist = input.next();
String title = input.next();
int year = input.nextInt();
Album albumObject = new Album(title,artist,year,rank);
if(albums.add(albumObject){
rank++;
} else{
throw new DuplicateAlbumException("album: " + title + " exists");
}
} catch(InputMissmatchException exc){
//print out an error about a bad line.
} catch(DuplicateAlbumException exc){
//print out an error about a duplicate album.
}
}
} catch(IOException e){
//problem with the file
}
One more thing, your Album class needs to override hashcode.
#Override
public int hashCode(){
return title.hashCode() + artist.hashCode();
}
I am reading from an text file Book.txt, and trying to create a Book object constructed as follows:
public Book(Person author, String title, String isbn, int year, BookGenre genre){
this.author = author;
this.title = title;
this.isbn = isbn;
this.year = year;
this.genre = genre;
}
Here is what a sample of the input file looks like:
Stieg Larsson 0 "The Girl with the Dragon Tattoo" 0307269752 2001 mystery
Brandon Stanton 0 "Humans of New York" 1250038820 2013 travel
Oscar Wilde 0 "The Importance of Being Earnest" 158049580X 1895 comic
Douglas Hofstadter 0 "Gödel, Escher, Bach: An Eternal Golden Braid" 0465026567 1979 science
I am not exactly sure what use the 0's could provide that are located after the author's name, so I will probably just delete them, unless you guys have any idea as to how they could be used.
Here is the code I am using to read in the file:
else if(name.equals("Book.txt")){
ArrayList<Book> p = new ArrayList<Book>();
BufferedReader br = new BufferedReader(new FileReader("Book.txt"));
String line = br.readLine();
while(line != null)
{
String [] tokens = line.split("\\s+");
p.add(new Book(new Person(tokens[0], tokens[1], Integer.parseInt(tokens[2])), tokens[3], tokens[4], Integer.parseInt(tokens[5]), tokens[6]));
line = br.readLine();
}
br.close();
}
I am getting an error which says
Exception in thread "main" java.lang.NumberFormatException: For input string: "with"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:59)
at java.lang.Integer.parseInt(Integer.java:460)
at java.lang.Integer.parseInt(Integer.java:510)
at SortingImplementation.main(SortingImplementation.java:43)
So I am pretty sure I am simply reading the file wrong. Does anyone see anything that can be changed to make it work better?
Don't see how your code compiles in the first place since you're expecting a BookGenre as the last parameter for your Book constructor and you're passing a String to it. But since that's not the issue described, let's just assume BookGenre class has a simple constructor taking in a String to fix things and you're actually calling that in the end.
Nevertheless, like BalusC pointed out, your problem is that you're expecting title to be just one word, which it in your example data is not.
If you really want to do this by splitting text by the word and parsing them, then follow up with this sort of logic (no, it's not a full solution as that'd require lots more lines, but should have enough hints there for you to figure out the rest):
private Book parseBookFromLine(String line) throws Exception {
String [] tokens = line.split("\\s+");
Person author = new Person(tokens[0], tokens[1], Integer.parseInt(tokens[2]));
String title = "";
int nextToken = 3;
/*
* Assume next token starts with quotation marks or throw an exception about
* malformed data.
*/
if (tokens[nextToken].endsWith("\"")) {
// Skim away the quotation.
String temp = tokens[nextToken++];
title = temp.substring(1, temp.length - 1);
} else {
/*
* Loop and keep updating the title until you find next token with
* quotation mark or there are only five tokens left. In the latter case,
* if no quotation marks found at the end of current token, throw exception
* again about malformed data.
*/
}
return new Book(author, title, tokens[nextToken++],
Integer.parseInt(tokens[nextToken++]),
new BookGenre(tokens[nextToken++])));
}
This code takes in users and movies from two separate files and computes a user score for a movie. When I run the code I get the following error:
Exception in thread "main" java.lang.NullPointerException
at RecommenderSystem.makeRecommendation(RecommenderSystem.java:75)
at RecommenderSystem.main(RecommenderSystem.java:24)
I believe the NullPointerException is due to an error in this particular class but I can't spot it. Any thoughts?
import java.io.*;
import java.lang.Math;
public class RecommenderSystem
{
private Movie[] m_movies;
private User[] m_users;
/** Parse the movies and users files, and then run queries against them.
*/
public static void main(String[] argv)
throws FileNotFoundException, ParseError, RecommendationError
{
FileReader movies_fr = new FileReader("C:\\workspace\\Recommender\\src\\IMDBTop10.txt");
FileReader users_fr = new FileReader("C:\\workspace\\Recommender\\src\\IMDBTop10-users.txt");
MovieParser mp = new MovieParser(movies_fr);
UserParser up = new UserParser(users_fr);
Movie[] movies = mp.getMovies();
User[] users = up.getUsers();
RecommenderSystem rs = new RecommenderSystem(movies, users);
System.out.println("Alice would rate \"The Shawshank Redemption\" with at least a "
+ rs.makeRecommendation("The Shawshank Redemption", "asmith"));
System.out.println("Carol would rate \"The Dark Knight\" with at least a "
+ rs.makeRecommendation("The Dark Knight", "cd0"));
}
/** Instantiate a recommender system.
*
* #param movies An array of Movie that will be copied into m_movies.
* #param users An array of User that will be copied into m_users.
*/
public RecommenderSystem(Movie[] movies, User[] users)
throws RecommendationError
{
m_movies = movies;
m_users = users;
}
/** Suggest what the user with "username" would rate "movieTitle".
*
* #param movieTitle The movie for which a recommendation is made.
* #param username The user for whom the recommendation is made.
*/
public double makeRecommendation(String movieTitle, String username)
throws RecommendationError
{
int userNumber;
int movieNumber;
int j=0;
double weightAvNum =0;
double weightAvDen=0;
for (userNumber = 0; userNumber < m_users.length; ++userNumber)
{
if (m_users[userNumber].getUsername().equals(username))
{
break;
}
}
for (movieNumber = 0; movieNumber < m_movies.length; ++movieNumber)
{
if (m_movies[movieNumber].getTitle().equals(movieTitle))
{
break;
}
}
// Use the weighted average algorithm here (don't forget to check for
// errors).
while(j<m_users.length){
if(j!=userNumber){
weightAvNum = weightAvNum + (m_users[j].getRating(movieNumber)- m_users[j].getAverageRating())*(m_users[userNumber].similarityTo(m_users[j]));
weightAvDen = weightAvDen + (m_users[userNumber].similarityTo(m_users[j]));
}
j++;
}
return (m_users[userNumber].getAverageRating()+ (weightAvNum/weightAvDen));
}
}
class RecommendationError extends Exception
{
/** An error for when something goes wrong in the recommendation process.
*
* #param s A string describing the error.
*/
public RecommendationError(String s)
{
super(s);
}
}
If the file you posted is unaltered from the file that generated the stack trace you posted, then the nullpointer exception on line 75 is somewhere in this code:
weightAvNum = weightAvNum + (m_users[j].getRating(movieNumber)- m_users[j].getAverageRating())*(m_users[userNumber].similarityTo(m_users[j]));
So since m_users is not null (otherwise it would have crashed earlier) either m_users[j] or m_users[userNumber] is null, i.e., there is some null element in the m_users array.