Related
I doing a bigger school project (first part of basic objective programming in java - so not touched extended, polyphorism etc yet, thats next part), but run in to a small problem and tried for couple of days to find solution (thru books and internet). I constructed different ArrayLists in one class and different classes (at least two) should get access to them.
public class Customer
{
public void subMenuCustomer()
{
............code............
int subMenuCust;
ServiceLogic addCustomer = new ServiceLogic();
ServiceLogic listAllCustomers = new ServiceLogic();
while(true)
{
System.out.println("Please Choose your preference: ");
System.out.println("Create account, press \"1\": ");
System.out.println("Get list of clustomers, press \"2\": ");
System.out.println("Log out, press \"0\": ";
subMenuCust = input.nextInt();
switch(subMenuCust)
{
case 1 ://Call method createCustomer in class ServiceTech to add new customers
addCustomer.createCustomer(name, lastname, ssNo);
break;
case 3
listAllCustomers.getCustomer();
............more code..............
}
}
When user has added details (social secuity number, name and lastname) it is stored in seperate ArrayList. These three ArrayList are added(merge/concat) together to a fourth ArayList, listCustomer , so that all elements from the three ArrayList end up in same index [101 -54 Clark Kent, 242-42 Linus Thorvalds, ...].
import java.util.ArrayList;
import java.util.Scanner;
public class ServiceLogic
{
//Create new ArrayLists of Strings
private ArrayList<String> listSSNoCustomers = new ArrayList<>();
private ArrayList<String> listNameCustomers = new ArrayList<>();
private ArrayList<String> listLastnameCustomers = new ArrayList<>();
private ArrayList<String> listCustomers;
Scanner input = new Scanner(System.in);
public boolean createCustomer(String name, String lastname, String ssNo) //
{
System.out.println("Write social security number; ");
ssNo = input.next();
//loop to check that it is a uniq social security number
for(String ssNumber : listSSNoCustomers)
{
if (ssNumber.equals(ssNo))
{
System.out.println("This customer already exist. Must be uniq social security number.");
return true;
}
}
//If social security number is not on list, add it
//and continue add first name and surname
listSSNoCustomers.add(ssNo);
System.out.println(ssNo);
System.out.println("Write firstname; ");
name = input.next();
listNameCustomers.add(name);
System.out.println(name);
System.out.println("Write lastnamame; ");
surname = input.next();
listSurnameCustomers.add(lastname);
System.out.println(lastname);
return false;
}
public void setListCustomer(ArrayList<String> listCustomers)
{
this.listCustomers = listCustomers;
}
public ArrayList<String> getCustomer()
{
//ArrayList<String> listCustomers = new ArrayList<>();
for(int i = 0; i <listSSNoCustomers.size(); i++)
{
listCustomers.add(listSSNoCustomers.get(i) + " " + listNameCustomers.get(i) + " " + listFirstnameCustomers.get(i));
}
System.out.println("customer" + listCustomers);
return listCustomers;
}
}
According to the specification we got, when user want to see list of all customer the outputs should be in format [666-66 Bruce Wayne, 242-42 Linus Thorvalds, ...].
When user (staff) choose to enter details in class Customer ( Case 1 ) it works and elements get stored in the Arraylists for social security numbers, name and lastname (have checked that) .
The problem: when I run I can add customers, but when I try to get a list of customer the output: [] . I tried different solution, but same output only empty between the brackets.
So the question, how do I get ouput to work when user choose case 2 to get a list of all cutomers?
public class Catalogue() {
private List<Book> booksAvailable;
private List<Book> booksRented:
public Catalogue() {
booksAvailable.add(new Book("Matrix", 1999, new Genre("SciFi"), 3));
booksAvailable.add(new Book("Jurassic Park", 1999, new Genre("SciFi"), 3));
boosAvailable.add(new Book("Terminator", 1999, new Genre("SciFi"), 3));
booksRented = new LinkedList<Book> ();
}
public void rentBook() {
System.out.println("Rent a book:");
System.out.println("Enter the title of a book you want to rent: ");
String name = In.NextLine();
for (Book book: booksAvailable) {
if (book.getName.equals(name)) {
System.out.println("Renting " + name);
booksAvailable.remove(book);
booksRented.add(book);
break;
} else {
System.out.println("No such books found");
}
}
}
}
While running this code can only rent the Matrix book. When I try to rent another book like Jurassic park it says that no books found. When I close the program and again run it and try to rent the second book then it again says the books not found. Please help me with this problem. What is the problem that i have in this code. Thanks
As others have pointer out modifying a list while you're iterating over it is dangerous.
I would recommend trying it with a HashMap instead, especially if name is the only field you're looking at.
public class Catalogue {
private Map<String, Book> booksAvailable;
private Map<String, Book> booksRented;
public Catalogue() {
booksAvailable = new HashMap<>();
booksAvailable.put("Matrix", new Book("Matrix", 1999, new Genre("SciFi"), 3));
booksAvailable.put("Jurassic Park", new Book("Jurassic Park", 1999, new Genre("SciFi"), 3));
booksAvailable.put("Terminator", new Book("Terminator", 1999, new Genre("SciFi"), 3));
booksRented = new HashMap<>();
}
public void rentBook() {
System.out.println("Rent a book:");
System.out.println("Enter the title of a book you want to rent: ");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
if (booksAvailable.containsKey(name)) {
Book book = booksAvailable.get(name);
System.out.println("Renting " + name);
booksAvailable.remove(name);
booksRented.put(name, book);
} else {
System.out.println("No such books found");
}
}
}
I just tried your code(after modifying it to compile) and it works.
However when running on for example Jurasic Park it will say that the book is not found and then it will rent it, because that print statement is in the for loop.
I tried rewriting it to use streams and optionals, and I got this code that seems to be working
public void rentBook() {
System.out.println("Rent a book:");
System.out.println("Enter the title of a book you want to rent: ");
String name = "Jurassic Park";
Optional<Book> book = booksAvailable.stream().filter(b -> b.name.equals(name)).findFirst();
if(book.isPresent()) {
System.out.println("Renting " + name);
booksAvailable.remove(book.get());
booksRented.add(book.get());
}
else
System.out.println("No such book found");
}
When you call booksAvailable.remove() it will effectively removed from current iteration.
Hence when you access next(), it might result in unexpected behavior.
Edit
You cannot rent other book other than first book because of your code handling.
You have System.out.println("No such books found"); in the else statement inside loop. So if you input a book other than the first book, the test fail and the statement is printed.
To correct this you can use a flag to indicate a book is found or not, and print the statement outside the loop;
boolean rented = false;
for (Book b : books) {
if (found) {
rented = true;
}
}
if (!rented) {
// print no such book message
}
I am getting the infamous NoSuchElementException when reading from a "|" delimited text file using the scanner class. I am taking the values of each token and assigning them to values within a separate class using setter methods. I can't seem to pinpoint the error.
Here is my code:
void readFromFile(String fileName)
{
operas.clear();
Scanner input = new Scanner(new File(fileName));
while(input.hasNextLine())
{
String line = input.nextLine();
Opera opera = new Opera();
StringTokenizer stringTokenizer = new StringTokenizer(line, "|");
while(stringTokenizer.hasMoreTokens())
{
opera.setTitle(stringTokenizer.nextToken());
opera.setComposer(stringTokenizer.nextToken());
opera.setYear(Integer.parseInt(stringTokenizer.nextToken()));
opera.setCity(stringTokenizer.nextToken());
opera.setSynopsis(stringTokenizer.nextToken());
opera.setLink(stringTokenizer.nextToken());
}
operas.add(opera);
}
input.close();
}
And the text file is written as such (sorry it's so lengthy):
Giulio Cesare|George Frideric Handel|1724|London|Tells the story loosely based on the events of the Roman Civil War (48-47 B.C.) in which Julius Caesar has defeated Pompey and gone to Alexandria in search of him. The kingdom, ruled by Cleopatra and younger brother Ptolemy, is met by Pompey pleading for refuge from his conqueror.|https://www.youtube.com/watch?v=M1UmvCaobDg
Carmen|Georges Bizet|1875|Paris|Set in Seville around the year 1830, the opera deals with the love and jealousy of Don José, who is lured away from his duty as a soldier and his beloved Micaëla by the gypsy factory-girl Carmen, whom he allows to escape from custody.|https://www.youtube.com/watch?v=zTDMvyj4TFg
Die ZauberFlote|Wolfgang Amadeus Mozart|1791|Vienna|The Queen of the Night persuades Prince Tamino to rescue her daughter Pamina from captivity under the high priest Sarastro; instead, he learns the high ideals of Sarastro's community and seeks to join it. Separately, then together, Tamino and Pamina undergo severe trials of initiation, which end in triumph, with the Queen and her cohorts vanquished. The earthy Papageno, who accompanies Tamino on his quest, fails the trials completely but is rewarded anyway with the hand of his ideal female companion Papagena.|https://www.youtube.com/watch?v=Fm-4LdLFr_E
Il Barbiere di Siviglia|Gioachino Rossini|1816|Rome|Count Almaviva comes in disguise to the house of Doctor Bartolo and serenades Rosina, whom Bartolo keeps confined to the house. Figaro the barber, who knows all the town's secrets and scandals, explains to Almaviva that Rosina is Bartolo's ward, not his daughter, and that the doctor intends to marry her.|https://www.youtube.com/watch?v=p97ym1HeCNI
Tosca|Giacomo Puccini|1900|Rome|Tosca is tale of romance over politics; featuring a heroic painter, a despicable ruler and an opera superstar, Tosca herself!|https://www.youtube.com/watch?v=xGDhQwsgMBQ
Salome|Richard Strauss|1905|Dresden|Under the bright moonlight, guard captain, Narraboth, intensely watches Princess Salome, with whom he is madly in love, from a terrace above the banquet hall as she dines with her stepfather and his court.|https://www.youtube.com/watch?v=kInyoCPyFb0
War and Peace|Sergei Prokofiev|1944|Moscow|Based on Tolstoy's literature of War and Peace, the world-weary Prince Andrei Bolkonsky encounters the youthful Natasha Rostova, first in the country, then at a ball in St Petersburg. Enchanted, he asks for her hand in marriage. Unfortunately Natasha has also aroused the curiosity of the dissolute Anatol Kuragin.|https://www.youtube.com/watch?v=2nhOeGhWWkU
Dido and Aeneas|Henry Purcell|1689|London|Tells the tale of the legendary Queen of Carthage, Dido, and the Trojan refugee prince, Aeneas. When Aeneas and his crew become shipwrecked in Carthage, he and the Queen fall in love. In the meantime, witches plot Dido's destruction.|https://www.youtube.com/watch?v=Q3Vs3YXQp5U
Norma|Vincenzo Bellini|1831|Milan|Gaul has been conquered by the Romans. Oroveso, the Arch-Druid longs to lead a Gallic rebellion against the colonial forces. He and all the others wait for the signal to be given by his daughter, the Druid High Priestess Norma. But Norma has fallen in love with the Roman Proconsul, Pollione, and given birth to two children. They have been brought up in secrecy by her confidante Clotilde. Norma still loves Pollione but he has fallen in love with a novice priestess, Adalgisa.|https://www.youtube.com/watch?v=GN75XDDm_DI
Rigoletto|Giuseppe Verdi|1851|Venice|Its tragic story revolves around the licentious Duke of Mantua, his hunch-backed court jester Rigoletto, and Rigoletto's beautiful daughter Gilda. A curse is placed on both the Duke and Rigoletto by a courtier whose daughter the Duke has seduced with Rigoletto's encouragement. The curse comes to fruition when Gilda falls in love with the Duke and sacrifices her life to save him from assassins hired by her father.|https://www.youtube.com/watch?v=nlr9jygEgwM
And the error I'm recieving:
Exception in thread "main" java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(StringTokenizer.java:349)
at Operas.OperasGUI.readFromFile(OperasGUI.java:118)
at Operas.OperasGUI.<init>(OperasGUI.java:45)
at Operas.OperasGUI.main(OperasGUI.java:607)
Another note is that the error at line 118 is the line where I'm setting the year, the only line I'm parsing a primitive value. Not sure if that has anything to do with it.
Any suggestions? If any more code or info is needed, I'd be happy to provide it.
Thank you.
EDIT:
Here is my complete Operas class:
package Operas;
public class Opera {
private String title;
private String composer;
private int year;
private String city;
private String synopsis;
private String link;
public Opera(){
title = "";
composer = "";
year = 0;
city = "";
synopsis = "";
link = "";
}
public Opera(String title, String composer, int year, String city,
String synopsis, String link)
{
this.title = title;
this.composer = composer;
this.year = year;
this.city = city;
this.synopsis = synopsis;
this.link = link;
}
public Opera(Opera anotherOpera)
{
title = anotherOpera.title;
composer = anotherOpera.composer;
year = anotherOpera.year;
city = anotherOpera.city;
synopsis = anotherOpera.synopsis;
link = anotherOpera.link;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getComposer() {
return composer;
}
public void setComposer(String composer) {
this.composer = composer;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getSynopsis() {
return synopsis;
}
public void setSynopsis(String synopsis) {
this.synopsis = synopsis;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
#Override
public String toString()
{
return "Opera{Title = " + title + ", Composer = " + composer + ", Year = " + year +
", City = " + city + ", Synopsis = " + synopsis + ", Link = " + link + '}';
}
public boolean equals(Opera opera)
{
return this.getTitle().equalsIgnoreCase(opera.getTitle()) &&
this.getComposer().equalsIgnoreCase(opera.getComposer());
}
}
Not sure if that helps.
Not sure what you are doing wrong here, the code I have which I believe mimicks your code is:
MAIN:
package helpMe;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;
import javax.swing.plaf.synth.SynthSeparatorUI;
public class getIt {
static ArrayList readFromFile(String fileName) throws FileNotFoundException
{
ArrayList<Opera> a = new ArrayList<Opera>();
Scanner input = new Scanner(new File(fileName));
while(input.hasNextLine())
{
String line = input.nextLine();
Opera opera = new Opera();
StringTokenizer stringTokenizer = new StringTokenizer(line, "|");
while(stringTokenizer.hasMoreTokens())
{
opera.setTitle(stringTokenizer.nextToken());
opera.setComposer(stringTokenizer.nextToken());
opera.setYear(Integer.parseInt(stringTokenizer.nextToken()));
opera.setCity(stringTokenizer.nextToken());
opera.setSynopsis(stringTokenizer.nextToken());
opera.setLink(stringTokenizer.nextToken());
}
a.add(opera);
}
input.close();
return a;
}
public static void main(String [] args) throws FileNotFoundException {
ArrayList<Opera> a = new ArrayList<Opera>();
a = readFromFile("thisIsAFile");
for(int i = 0; i< a.size(); i++) {
Opera o = a.get(i);
System.out.println(o.toString());
}
}
}
OPERA CLASS:
package helpMe;
public class Opera {
private String Title;
private String City;
private int Year;
private String Composer;
private String Synopsis;
private String Link;
public Opera(String t, String c, int y, String co, String s, String l) {
Title = t;
City = c;
Year = y;
Composer = co;
Synopsis = s;
Link = l;
}
public Opera() {
Title = "";
City = "";
Year = 0;
Composer = "";
Synopsis = "";
Link = "";
}
public String setTitle(String t) {
return Title = t;
}
public String setCity(String c) {
return City = c;
}
public int setYear(int y) {
return Year = y;
}
public String setComposer(String co) {
return Composer = co;
}
public String setSynopsis(String s) {
return Synopsis = s;
}
public String setLink(String l) {
return Link = l;
}
public String toString() {
String s = Title + City + Composer;
return s;
}
}
TEXT FILE:
Giulio Cesare|George Frideric Handel|1724|London|Tells the story loosely based on the events of the Roman Civil War (48-47 B.C.) in which Julius Caesar has defeated Pompey and gone to Alexandria in search of him. The kingdom, ruled by Cleopatra and younger brother Ptolemy, is met by Pompey pleading for refuge from his conqueror.|https://www.youtube.com/watch?v=M1UmvCaobDg
Carmen|Georges Bizet|1875|Paris|Set in Seville around the year 1830, the opera deals with the love and jealousy of Don José, who is lured away from his duty as a soldier and his beloved Micaëla by the gypsy factory-girl Carmen, whom he allows to escape from custody.|https://www.youtube.com/watch?v=zTDMvyj4TFg
Die ZauberFlote|Wolfgang Amadeus Mozart|1791|Vienna|The Queen of the Night persuades Prince Tamino to rescue her daughter Pamina from captivity under the high priest Sarastro; instead, he learns the high ideals of Sarastro's community and seeks to join it. Separately, then together, Tamino and Pamina undergo severe trials of initiation, which end in triumph, with the Queen and her cohorts vanquished. The earthy Papageno, who accompanies Tamino on his quest, fails the trials completely but is rewarded anyway with the hand of his ideal female companion Papagena.|https://www.youtube.com/watch?v=Fm-4LdLFr_E
Il Barbiere di Siviglia|Gioachino Rossini|1816|Rome|Count Almaviva comes in disguise to the house of Doctor Bartolo and serenades Rosina, whom Bartolo keeps confined to the house. Figaro the barber, who knows all the town's secrets and scandals, explains to Almaviva that Rosina is Bartolo's ward, not his daughter, and that the doctor intends to marry her.|https://www.youtube.com/watch?v=p97ym1HeCNI
Tosca|Giacomo Puccini|1900|Rome|Tosca is tale of romance over politics; featuring a heroic painter, a despicable ruler and an opera superstar, Tosca herself!|https://www.youtube.com/watch?v=xGDhQwsgMBQ
Salome|Richard Strauss|1905|Dresden|Under the bright moonlight, guard captain, Narraboth, intensely watches Princess Salome, with whom he is madly in love, from a terrace above the banquet hall as she dines with her stepfather and his court.|https://www.youtube.com/watch?v=kInyoCPyFb0
War and Peace|Sergei Prokofiev|1944|Moscow|Based on Tolstoy's literature of War and Peace, the world-weary Prince Andrei Bolkonsky encounters the youthful Natasha Rostova, first in the country, then at a ball in St Petersburg. Enchanted, he asks for her hand in marriage. Unfortunately Natasha has also aroused the curiosity of the dissolute Anatol Kuragin.|https://www.youtube.com/watch?v=2nhOeGhWWkU
Dido and Aeneas|Henry Purcell|1689|London|Tells the tale of the legendary Queen of Carthage, Dido, and the Trojan refugee prince, Aeneas. When Aeneas and his crew become shipwrecked in Carthage, he and the Queen fall in love. In the meantime, witches plot Dido's destruction.|https://www.youtube.com/watch?v=Q3Vs3YXQp5U
Norma|Vincenzo Bellini|1831|Milan|Gaul has been conquered by the Romans. Oroveso, the Arch-Druid longs to lead a Gallic rebellion against the colonial forces. He and all the others wait for the signal to be given by his daughter, the Druid High Priestess Norma. But Norma has fallen in love with the Roman Proconsul, Pollione, and given birth to two children. They have been brought up in secrecy by her confidante Clotilde. Norma still loves Pollione but he has fallen in love with a novice priestess, Adalgisa.|https://www.youtube.com/watch?v=GN75XDDm_DI
Rigoletto|Giuseppe Verdi|1851|Venice|Its tragic story revolves around the licentious Duke of Mantua, his hunch-backed court jester Rigoletto, and Rigoletto's beautiful daughter Gilda. A curse is placed on both the Duke and Rigoletto by a courtier whose daughter the Duke has seduced with Rigoletto's encouragement. The curse comes to fruition when Gilda falls in love with the Duke and sacrifices her life to save him from assassins hired by her father.|https://www.youtube.com/watch?v=nlr9jygEgwM
OUTPUT
Giulio CesareLondonGeorge Frideric Handel
CarmenParisGeorges Bizet
Die ZauberFloteViennaWolfgang Amadeus Mozart
Il Barbiere di SivigliaRomeGioachino Rossini
ToscaRomeGiacomo Puccini
SalomeDresdenRichard Strauss
War and PeaceMoscowSergei Prokofiev
Dido and AeneasLondonHenry Purcell
NormaMilanVincenzo Bellini
RigolettoVeniceGiuseppe Verdi
Not sure if that helps but it seems to work just fine and I run into no problems reading from the text file at all.
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();
}
Trying to insert a file like this into the database
Actor: Taylor Lautner
Bio: Taylor Daniel Lautner was born in Grand Rapids, Michigan to parents, Deborah and Daniel Lautner. He, and younger sister Makena, were raised in a well-mannered, Roman Catholic household in Hudsonville, Michigan. At the age of six, Taylor began studying martial arts at Fabiano"s Karate School and he, along with his family, quickly noticed his unique and natural talent for the sport. He was soon invited to train with seven-time world karate champion Michael Chaturantabut (aka Mike Chat) and, at the age of eight, he was asked to represent his country in the twelve years and under division in the World Karate Association where he became the Junior World Forms and Weapons champion, winning three gold medals. In 2003, Taylor continued to flourish in the martial arts circuit where he ranked number one in the world for NASKA"s Black Belt Open Forms, Musical Weapons, Traditional Weapons and Traditional Forms and, at the age of twelve, he became the three time Junior World Champion.
More_Bio: However, in addition to his love for martial arts, Taylor quickly developed a love for acting at the age of seven years old when his martial arts instructor, who was involved in show business, encouraged him to audition for a small appearance in a Burger King commercial. Although he was unsuccessful, he enjoyed the experience so much that he told his parents that he wanted to pursue a career in acting. Soon, he and his family were traveling back-and-forth from their home in Michigan to California so Taylor could audition for acting roles on a regular basis. When Taylor was ten, with the frequent traveling and air fares starting to become overwhelming, his family made the crucial decision to relocate to Los Angeles where Taylor would have the advantage of being able to audition for films, television, and commercials full-time.
Reason: This is one hunky teen idol! I loved him as Jacob Black in the "Twilight" series! He is one of the best-looking guys I"ve ever seen. I was so excited when I tweeted him and he replied back once!
Fact: He played football during his freshman and sophomore year of high school. He is of German, French, Dutch, and Native American (specifically Ottawa and Potawatomi) descent. Omg! And we both like the band Kings of Leon.
Actor: Robert Pattinson
Bio: He was born on May 13, 1986, in London, England. He enjoys music and is an excellent musician, playing both the guitar and piano. When Robert was 15, he started acting in amateur plays with the Barnes Theatre Company. Afterward, he took screen role like Curse of the Ring (2004) (TV) (Kingdom of Twilight) as Giselher.
More_Bio: In 2003, Robert took on the role of Cedric Diggory in Harry Potter and the Goblet of Fire (2005). He got his role a week later after meeting Mike Newell in late 2003. He has since been cast as Edward Cullen in the highly-anticipated film, Twilight (2008/I). His music will also be heard in the film. Additionally, Robert has completed upcoming roles as Salvador Dalí in Little Ashes (2008) and Art in How to Be (2008).
Reason : Quirky, Robert Pattinson took my breath away when I first saw him as Cedric Diggory in "Harry Potter," but stole my heart when I saw him as s vampire Edward Cullen in "Twilight." Team Edward For the Win!! I just love his messy hair and thick eyebrows.
Fact: : He is an excellent musician and plays both the guitar and piano. He began taking piano lessons at age three, and classical guitar at five.
This is the code to do the insertion
String Actor = "", Bio = "", More_Bio = "", Fact ="", Reason = "";
while ((it = br.readLine()) != null) {
if (it.startsWith("Actor: "))
{
it = it.replace("'", "\"");
// remove actor
it = it.replace("Actor: ", " ");
Actor = it;
System.out.println(Actor);
// ps.setString(1, Actor);
}
if (it.startsWith("Bio:"))
{
it = it.replace("'", "\"");
// remove actor
it = it.replace("Bio: ", " ");
Bio = it;
System.out.println(Bio);
// ps.setString(2, Bio);
}
if (it.startsWith("More_Bio:"))
{
it = it.replace("'", "\"");
// remove actor
it = it.replace("More_Bio: ", " ");
More_Bio = it;
System.out.println(More_Bio);
// ps.setString(3, More_Bio);
}
if (it.startsWith("Reason:"))
{
it = it.replace("'", "\"");
// remove actor
it = it.replace("Reason: ", " ");
Reason = it;
System.out.println(Reason);
// ps.setString(4, Reason);
}
if (it.startsWith("Fact:"))
{
it = it.replace("'", "\"");
// remove actor
it = it.replace("Fact: ", " ");
Fact = it;
System.out.println(Fact);
// ps.setString(5, Fact);
}
ps.setString(1, Actor);
ps.setString(2, Bio);
ps.setString(3, More_Bio);
ps.setString(4, Reason);
ps.setString(5, Fact);
ps.executeUpdate();
}
ps.close();
con.close();
If the code has ps statements inside the loop, Information for Taylor Lautner and Robert Pattinson is inserted to the database twice, when i take it out of the while loop, only the last, Robert Pattinson is inserted. Taylor is ignored.
Your approach to getting the data is wrong. What you're trying to do is execute an update statement each time you find an actor or a bio or any such keyword. This is wrong, you should try to gather all the information first and then execute an update.
I would suggest the following approach:
Create a POJO and fill up all the information about the actor in POJO through your while loop. Maintain this in a map (where your key might be the actor's name)
Then iterate through the map, retrieve the information from the POJO for each key and create a update statement and execute your command.
A sample code might be something like this:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
public class TextReader {
public static void main(String[] args) {
new TextReader().reader();
}
public void reader() {
BufferedReader br = null;
String it;
String Actor = "", Bio = "", More_Bio = "", Fact = "", Reason = "";
try {
HashMap<String, PersonData> informationMap = new HashMap<String, TextReader.PersonData>();
br = new BufferedReader(new FileReader(new File("textFile.txt")));
while ((it = br.readLine()) != null) {
if (it.startsWith("Actor: ")) {
it = it.replace("'", "\"");
// remove actor
it = it.replace("Actor: ", " ");
Actor = it;
// System.out.println(Actor);
// ps.setString(1, Actor);
}
PersonData dataVO = informationMap.containsKey(Actor) ? informationMap.get(Actor) : new PersonData();
if (it.startsWith("Bio:")) {
it = it.replace("'", "\"");
// remove actor
it = it.replace("Bio: ", " ");
Bio = it;
// System.out.println(Bio);
dataVO.setBio(Bio);
// ps.setString(2, Bio);
}
if (it.startsWith("More_Bio:")) {
it = it.replace("'", "\"");
// remove actor
// it = it.replace("More_Bio: ", " ");
More_Bio = it;
// System.out.println(More_Bio);
dataVO.setMoreBio(More_Bio);
// ps.setString(3, More_Bio);
}
if (it.startsWith("Reason:")) {
it = it.replace("'", "\"");
// remove actor
it = it.replace("Reason: ", " ");
Reason = it;
dataVO.setReason(Reason);
// System.out.println(Reason);
// ps.setString(4, Reason);
}
if (it.startsWith("Fact:")) {
it = it.replace("'", "\"");
// remove actor
it = it.replace("Fact: ", " ");
Fact = it;
dataVO.setFact(Fact);
// System.out.println(Fact);
// ps.setString(5, Fact);
}
// System.out.println(Actor + "\t" + Bio + "\t" + More_Bio + "\t"
// + Reason + "\t" + Fact);
informationMap.put(Actor, dataVO);
}
for(String actorName: informationMap.keySet()){
PersonData dataVO = informationMap.get(actorName);
System.out.println(actorName);
// === Create your preparedstatement heare and execute the update ====
}
} catch (Exception exe) {
} finally {
if (br != null) {
try {
br.close();
} catch (IOException ex) {
}
}
}
}
Your sample POJO class might look something like this:
/**
* Sample Person POJO class
*/
public class PersonData {
private String bio;
private String moreBio;
private String fact;
private String reason;
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
public String getMoreBio() {
return moreBio;
}
public void setMoreBio(String moreBio) {
this.moreBio = moreBio;
}
public String getFact() {
return fact;
}
public void setFact(String fact) {
this.fact = fact;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
}
}
Note
Java naming convention states that variable names should start with a lower case. Although I followed what you had in your code for consistency's sake, I would highly recommend that you refactor your variable names
I've made one base assumption that your actor name would be unique. That is why I used it as a key in this case. If this is not true, then you might want to consider having the actor name as part of the POJO class and use another unique identifier as your key.