【问题标题】:Write a Java program for an inventory report using objects created from a text file使用从文本文件创建的对象为库存报告编写 Java 程序
【发布时间】:2014-09-19 14:28:07
【问题描述】:

我有一个学校项目,但无法正确编译。

可以在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

非常感谢您对这些问题的任何帮助。

【问题讨论】:

  • 第 46 行是什么? (su.cse2123.ProductTest.loadProducts(ProductTest.java:46))

标签: java arraylist inventory


【解决方案1】:

你一次读一个单词。目前Scanner 正在读取您的文件,如下所示:

inFile.next() =
inFile.next() = 肖申克

提示:inFile.nextLine() = 肖申克的救赎

【讨论】:

    【解决方案2】:

    你的问题在于while循环阅读评分:

    while(inFile.nextInt() != -1){
        pr.addUserRating(inFile.nextInt());
    }
    

    循环的每一轮读取 两个 项 - 一个在 while 条件中,另一个在循环内。由于在收视率结束后有一个String(下一个标题),如果有偶数个收视率,当你试图将它解释为int 时,你会在这里失败(如果它没有失败,你会只是得到错误的结果,因为你跳过了一半的评级)。解决此问题的一种方法是将评分提取到局部变量:

    int rating;
    while(rating = inFile.nextInt() != -1){
        pr.addUserRating(rating);
    }
    

    【讨论】:

      【解决方案3】:

      我建议您了解您连续调用 readInt 的次数。想象一下另一种读取值、检查它并在不重新读取的情况下重用它的方法。

      【讨论】:

        【解决方案4】:

        如果没有更好的文件格式(没有行尾),您需要使用正则表达式匹配:

        类似这样的:

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

        【讨论】:

          【解决方案5】:

          InputMismatchException 在您从 Scanner 实例调用 nextDouble()nextInt() 而不是输入数字时出现。错误消息显示该缺陷存在于loadProducts 方法中。 在该方法中,您调用next() 以获取产品名称和库存代码。但是,由于您的产品名称包含空格,因此您应该调用nextLine()

          在您的程序中发生的情况是:在 "The Shawshank Redemption" 上调用 next() 将返回 "The"。当您到达pr.setQuantity(inFile.nextInt()); 时,您的程序将抛出InputMismatchException,因为它试图从"Redemption" 中读取一个整数。

          还要考虑 mureinik 的建议: https://stackoverflow.com/a/25936439/4056420

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-29
            • 1970-01-01
            • 2022-01-18
            • 1970-01-01
            相关资源
            最近更新 更多