我有一个学校的项目,我无法正确编译。
可以在this链接找到相关说明。
我相信我在 Product.java 中正确创建了类。我的代码如下:
import java.util.*;
public class Product {
// Private member variables go here - you will need to add them yourself.
private String name;
private String code;
private int quantity;
private double price;
private String type;
private ArrayList<Integer> userRatings;
/*
* Product constructor
*/
public Product() {
name = "";
code = "";
quantity = 0;
price = 0;
type = "";
userRatings = new ArrayList<Integer>();
}
/*
* setName
* @param name - new name for the product
*/
public void setName(String name) {
this.name = name;
}
/*
* getName
* @return the name of the product
*/
public String getName() {
return name;
}
/*
* setType
* @param type - the type of the product
*/
public void setType(String type) {
this.type = type;
}
/*
* getType
* @return - the product type
*/
public String getType() {
return type;
}
/*
* setPrice
* @param price - the price of the product
*/
public void setPrice(double price) {
this.price = price;
}
/*
* getPrice
* @return the price of the product
*/
public double getPrice() {
return price;
}
/*
* setQuantity
* @param quantity - the number of this product in inventory
*/
public void setQuantity(int quantity) {
this.quantity = quantity;
}
/*
* getQuantity
* @return the number of this product in inventory
*/
public int getQuantity() {
return quantity;
}
/*
* setInventoryCode
* @param code - the new inventory code for the product
*/
public void setInventoryCode(String code) {
this.code = code;
}
/*
* getInventoryCode
* @return the inventory code of the product
*/
public String getInventoryCode() {
return code;
}
/*
* addUserRating
* NOTE: Each individual rating is stored with the product, so you need to maintain a list
* of user ratings. This method should append a new rating to the end of that list
* @param rating - the new rating to add to this product
*/
public void addUserRating(int rating) {
userRatings.add(rating);
}
/*
* getUserRating
* NOTE: See note on addUserRating above. This method should be written to allow you
* to access an individual value from the list of user ratings
* @param index - the index of the rating we want to see
* @return the rating indexed by the value index
*/
public int getUserRating(int index) {
return userRatings.get(index);
}
/*
* getUserRatingCount
* NOTE: See note on addUserRating above. This method should be written to return
* the total number of ratings this product has associated with it
* @return the number of ratings associated with this product
*/
public int getUserRatingCount() {
return userRatings.size();
}
/*
* getAvgUserRating
* NOTE: see note on addUserRating above. This method should be written to compute
* the average user rating on demand from a stored list of ratings.
* @return the average rating for this product as a whole integer value (use integer math)
*/
public int getAvgUserRating() {
int sum = 0;
if(userRatings.size() > 0){
for (int i = 0; i < userRatings.size(); i++){
sum += userRatings.get(i);
}
return sum / userRatings.size();
}
else return 0;
}
}
但问题在于测试代码。我尝试了多种方法并且不断出现InputMismatchException
错误。对于第2部分,我将需要ArrayList
个Product对象,因此我尝试将其合并到测试代码中。以下是 ProductTest.java :
import java.util.*;
import java.io.*;
public class ProductTest {
/*
* A simple main loop to load product objects from a file
* and then display them to the console
*/
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter an inventory filename: ");
String fname = keyboard.nextLine();
ArrayList<Product> products = loadProducts (fname);
displayProducts(products);
}
/*
* loadProducts
* Given a filename, opens the file and reads Products from
* the file into an ArrayList of Product objects. Returns the
* Arraylist.
*
* @param fname - String containing the input file name
* @return - An ArrayList of Product objects
*/
public static ArrayList<Product> loadProducts(String fname) {
ArrayList<Product> products = new ArrayList<Product>();
try {
Scanner inFile = new Scanner(new File(fname));
while (inFile.hasNext()) {
Product pr = new Product();
pr.setName(inFile.next());
pr.setInventoryCode(inFile.next());
pr.setQuantity(inFile.nextInt());
pr.setPrice(inFile.nextDouble());
pr.setType(inFile.next());
while(inFile.nextInt() != -1){
pr.addUserRating(inFile.nextInt());
}
products.add(pr);
}
inFile.close();
}
catch(IOException e) {
System.out.println("ERROR: "+e);
}
return products;
}
/*
* displayProducts
* Given an ArrayList of Product objects, outputs them
* to the console in the specified format.
*
* The format for this method is:
* NAME, INVENTORY_CODE, QUANTITY, PRICE, TYPE, RATING
*
* @param products - ArrayList of Product objects
*/
public static void displayProducts(ArrayList<Product> products) {
for(int i = 0; i<products.size(); i++) {
Product tmpProduct = products.get(i);
System.out.println(tmpProduct.getName());
System.out.println(tmpProduct.getInventoryCode());
System.out.println(tmpProduct.getQuantity());
System.out.println(tmpProduct.getPrice());
System.out.println(tmpProduct.getType());
System.out.println(tmpProduct.getAvgUserRating());
System.out.println();
}
}
}
这是运行当前ProductTest产生的错误消息:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:840)
at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextInt(Scanner.java:2091)
at java.util.Scanner.nextInt(Scanner.java:2050)
at osu.cse2123.ProductTest.loadProducts(ProductTest.java:46)
at osu.cse2123.ProductTest.main(ProductTest.java:23)
我正在使用的文本文件包含以下内容:
The Shawshank Redemption
C0000001
100
19.95
DVD
4
5
3
1
-1
The Dark Knight
C0000003
50
19.95
DVD
5
2
3
-1
Casablanca
C0000007
137
9.95
DVD
5
4
5
3
-1
The Girl With The Dragon Tattoo
C0000015
150
14.95
Book
4
4
2
-1
Vertigo
C0000023
55
9.95
DVD
5
5
3
5
2
4
-1
A Game of Thrones
C0000019
100
8.95
Book
-1
对此问题的任何帮助都将不胜感激。
答案 0 :(得分:5)
您一次只读一个字。目前,Scanner正在阅读您的文件,如下所示:
inFile.next()=中
inFile.next()= Shawshank
提示:inFile.nextLine()= Shawshank Redeption
答案 1 :(得分:1)
您的问题在于while
循环阅读评分:
while(inFile.nextInt() != -1){
pr.addUserRating(inFile.nextInt());
}
每轮循环读取两个项 - 一个在while
条件下,另一个在循环内。由于评分结束后有一个String
(下一个标题),如果有一个偶数个评级,那么在尝试将其解释为int
时会失败(如果不是失败你只是得到错误的结果,因为你正在跳过一半的评级)。解决此问题的一种方法是将评级提取到本地变量:
int rating;
while(rating = inFile.nextInt() != -1){
pr.addUserRating(rating);
}
答案 2 :(得分:0)
我建议您了解连续多次调用readInt。想象一下另一种读取值,检查它并重复使用它而无需重新读取的方法。
答案 3 :(得分:0)
如果没有更好的格式化文件(没有行尾),则需要使用正则表达式匹配:
这样的事情:
public static ArrayList<Product> loadProducts(String fname) {
ArrayList<Product> products = new ArrayList<Product>();
Pattern p = Pattern.compile("([\\w ]*) (C[0-9]*) (\\d*) ([\\d\\.]*) (\\w*) ([\\d -]*)");
Matcher m = p.matcher(fname);
while (m.find()) {
Product pr = new Product();
pr.setName(m.group(1));
pr.setInventoryCode(m.group(2));
pr.setQuantity(Integer.parseInt(m.group(3)));
pr.setPrice(Double.parseDouble(m.group(4)));
pr.setType(m.group(5));
for (String rate : m.group(6).split(" ")) {
pr.addUserRating(Integer.parseInt(rate));
}
products.add(pr);
System.out.println(pr);
}
return products;
}
答案 4 :(得分:0)
当您从扫描仪实例调用InputMismatchException
或nextDouble()
而您输入的数字不是数字时,会发生nextInt()
。错误消息显示该缺陷位于loadProducts
方法中。
在该方法中,您可以拨打next()
来获取产品名称和广告资源代码。但是,由于您的商品名称包含空格,因此您应该拨打nextLine()
。
您的计划会发生以下情况:在next()
上致电"The Shawshank Redemption"
将返回"The"
。当您到达pr.setQuantity(inFile.nextInt());
时,您的程序将抛出InputMismatchException
,因为它会尝试从"Redemption"
读取整数。
还考虑到mureinik的建议: https://stackoverflow.com/a/25936439/4056420