Reputation: 21
How can I can read my text file into the array list of Book type that shall be able to be modified in the program?
[Edited] I have edited my code to copy each string into one Book type. But it returns error as shown:
Exception in thread "main" java.lang.NumberFormatException: For input string: "eillance Valley"
May I know how to solve this?
p.s. I am trying on GUI approach in my main class, just in case it matters.
This is my text file (booklist.txt):
9781785785719,Surveillance Valley,Yasha Levine,Political Science,57.95,NONE
9780241976630,How to Speak Machine,John Maeda,Non-Fiction,89.95,NONE
9781119055808,R For Dummies,Andre De Vries,Design,107.77,NONE
9780062018205,Predictably Irrational,Dan Ariely,Legal opinion,39.90,NONE
9780008327613,The Globalist,John Waish,Non-Fiction,109.90,NONE
9780525538349,Measure What Matters,John Doerr,Management,86.95,NONE
9780807092156,Man's Search for Meaning,Viktor Frankl,Biography,49.90,NONE
This is my file-reading code:
import java.util.ArrayList;
import java.util.Scanner;
import java.io.*;
public class FileReadDemo {
public static void main(String[] args) {
//ArrayList<String> arrayList = new ArrayList<>();
ArrayList<Book> bookList = new ArrayList<>();
try (Scanner s = new Scanner(new File("c:/Users/brightnow/Documents/booklist.txt")).useDelimiter(",")) {
while (s.hasNext()) {
// bookList.add(s.next()); // does not work
//arrayList.add(s.nextLine());
String[] bookInfo = s.next().split(",");
for (int i = 0; i < bookInfo.length; i++) {
String ISBN = bookInfo[i].substring(0);
String title = bookInfo[i].substring(1);
String author = bookInfo[i].substring(2);
String genre = bookInfo[i].substring(3);
String price = bookInfo[i].substring(4);
String borrower = bookInfo[i].substring(5);
Double price2 = Double.parseDouble(price); // error here?
bookList.add(new Book(ISBN, title, author, genre, price2, borrower));
}
}
}
catch (FileNotFoundException e) {
// Handle the potential exception
}
// data are broke down into pieces?
for(int i = 0; i < bookList.size(); i++)
System.out.println(bookList.get(i));
// data showed as list with "," as delimiter?
System.out.println(bookList);
}
}
This is my Book type:
public class Book {
private String ISBN;
private String title;
private String author;
private String genre;
private double price;
private String borrower;
public Book(String ISBN, String title, String author, String genre, Double price) {
ISBN = this.ISBN;
title = this.title;
author = this.author;
genre = this.genre;
price = this.price;
borrower = "NONE"; // set default no borrower
}
public String getISBN() {
return ISBN;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public String getGenre() {
return genre;
}
public double getPrice() {
return price;
}
public String getBorrower() {
return borrower;
}
public void setISBN(String aISBN) {
ISBN = aISBN;
}
public void setTitle(String aTitle) {
title = aTitle;
}
public void setAuthor(String aAuthor) {
author = aAuthor;
}
public void setGenre(String aGenre) {
genre = aGenre;
}
public void setPrice(double aPrice) {
price = aPrice;
}
public void setBorrower(String aBorrower) {
borrower = aBorrower;
}
}
Upvotes: 0
Views: 2792
Reputation: 11946
You could write another constructor in you Book class:
public Book(String raw) {
String[] data = raw.split(",");
ISBN = data[0];
title = data[1];
author = data[2];
genre = data[3];
price = data[4]; //add conversion to Double here, if needed
borrower = "NONE";
Then you can just create and add the new Book to you list:
bookList.add(new Book(s.nextLine()));
In order to make it a bit more elegant, you can change the litterals to define the position of each value to constants:
private static final int POS_ISBN = 0;
and then:
ISBN = data[POS_ISBN];
and so on.
Upvotes: 0
Reputation: 8096
I'd do that like this in Kotlin:
import java.io.*
data class Book(
var ISBN: String,
var title: String,
var author: String,
var genre: String,
var price: Double,
var borrower: String
)
operator fun <T> List<T>.component6() = this[5]
fun main() {
val books = File("c:/Users/brightnow/Documents/booklist.txt").useLines { // open and close stream
it.map { line -> // map each line of Sequence<T> to Book
line.split(",").let { (iSBN, title, author, genre, price, borrower) ->
Book(iSBN, title, author, genre, price.toDouble(), borrower)
}
}
}.toList() // start the operation
}
For Java, I'll do it like this:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
// class Book{...}
public final class FileReadDemo {
public static void main() {
List<Book> books = new ArrayList<>();
try {
BufferedReader in = new BufferedReader(new FileReader("c:/Users/brightnow/Documents/booklist.txt"));
String lineText;
while ((lineText = in.readLine()) != null) {
// split the line with delimiter
String[] line = lineText.split(",");
// create new Book and add that to the list
books.add(new Book(line[0], line[1], line[2], line[3], Double.parseDouble(line[4]), line[5]));
}
in.close();
} catch (IOException e) {
System.out.println("File Read Error");
}
}
}
Upvotes: 1
Reputation: 541
Scanner.hasNext()
returns a String
. Your bookList
is an ArrayList<Book>
. You need to create instances of Book
before you can add them to bookList
.
EDIT
Sebastian Lopez's answer shows you how to change the reading of each line from the file so that you can split()
the line string into an array of pieces.
You'll still have to feed those to your Book
constructor, and for any value that's not a String
, e.g. a Double
, you need to do the type conversion.
Upvotes: 0
Reputation: 2256
bookList.add(s.next());
will not work because s.next()
does not return an instance of Book
. What you can do is store the value returned by s.next()
into an ArrayList of String like you are doing, and then iterate through that ArrayList and construct a new Book
that you can store in bookList
since you already have your tokens that s.next()
returns split using the comma as a delimiter.
Upvotes: 0
Reputation: 759
To split your String by comma(,) use str.split(",")
try {
BufferedReader in = new BufferedReader(
new FileReader("c:/Users/brightnow/Documents/booklist.txt"));
String str;
while ((str = in.readLine())!= null) {
String[] bookLine=str.split(",");
// Create an object from bookLine
// Add the object to an Array
}
in.close();
} catch (IOException e) {
System.out.println("File Read Error");
}
Upvotes: 0