读取文本文件时的数字格式异常

时间:2015-08-13 10:33:09

标签: java

我正在阅读包含多列数据集的文本文件。我正在使用Memreader,我已将每列分配为索引,以便将输出打印到目标文件。然而,对于我的生活,我无法弄清楚为什么我一直得到这个'数字格式例外'。我已经完成了通常的obj.nextLine()跳过标题,我已经为数据集中的所有值分配了'int'数据类型,并确保数据集只有int值,以便于测试但仍然得到错误。这是我的代码:

   public class MemReader implements Serializable{

private static final long serialVersionUID = 7526472295622776147L;

public OpenIntObjectHashMap movieToCust;
public OpenIntObjectHashMap custToMovie;
public OpenIntIntHashMap sumByCust;
public OpenIntIntHashMap sumByMovie;


/**
 * Default constructor. Initializes hashtables. 
 */
public MemReader() {
    movieToCust = new OpenIntObjectHashMap();
    custToMovie = new OpenIntObjectHashMap();    
    sumByCust = new OpenIntIntHashMap();
    sumByMovie = new OpenIntIntHashMap();
}


/**
 * Reads a text file in the form 
 *
 * mid,uid,rating
 *
 * and stores this data in the custToMovie and 
 * movieToCust hashtables. 
 *
 * @param  fileName  The file containing the movie
 *                   data in the specified format.
 */
public void readData(String fileName) {

    try {

        Scanner in = new Scanner(new File(fileName));

        String[] line;
        int mid;   //user-id
        int uid; //isbn
        int rating;  //book rating
        //String date;


        while(in.hasNextLine()) {

            line = in.nextLine().split(", ");
            mid = Integer.parseInt(line[0]);
            uid = Integer.parseInt(line[1]);  //isbn change
            rating = Integer.parseInt(line[2]);

            addToMovies(mid, uid, rating);
            addToCust(mid, uid, rating);

        }
    }
    catch(FileNotFoundException e) {
        System.out.println("Can't find file " + fileName);
        e.printStackTrace();

    }
    catch(IOException e) {
        System.out.println("IO error");
        e.printStackTrace();
    }
}


/**
 * Serializes a MemReader object so that it can be
 * read back later. 
 *
 * @param  fileName  The file to serialize to. 
 * @param  obj  The name of the MemReader object to serialize.
 */
public static void serialize(String fileName, MemReader obj) {

    try {
        FileOutputStream fos = new FileOutputStream(fileName);
        ObjectOutputStream os = new ObjectOutputStream(fos);
        os.writeObject(obj);
        os.close();
    }
    catch(FileNotFoundException e) {
        System.out.println("Can't find file " + fileName);
        e.printStackTrace();
    }
    catch(IOException e) {
        System.out.println("IO error");
        e.printStackTrace();
    }
}


/**
 * Deserializes a previously serialized MemReader object. 
 *
 * @param  fileName  The file containing the serialized object. 
 * @return The deserialized MemReader object. 
 */
public static MemReader deserialize(String fileName)
{
    try {
        FileInputStream fis = new FileInputStream(fileName);
        ObjectInputStream in = new ObjectInputStream(fis);

        return (MemReader) in.readObject();
    }
    catch(ClassNotFoundException e) {
        System.out.println("Can't find class");
        e.printStackTrace();
    }
    catch(IOException e) {
        System.out.println("IO error");
        e.printStackTrace();
    }

    //We should never get here
    return null;
}




/**
 * Adds an entry to the movieToCust hashtable. The
 * uid and rating are packed into one int to 
 * conserve memory. 
 *
 * @param  mid  The movie id. 
 * @param  uid  The user id. 
 * @param  rating  User uid's rating for movie mid.
 */
//NOTE THIS EDITED PART
public void addToMovies(int mid, int uid, int rating) {

    IntArrayList list;

    if(mid == 0 && uid == 0)
        return;

    if(movieToCust.containsKey(mid)) {
        list = (IntArrayList) movieToCust.get(mid);
    }
    else {
        list = new IntArrayList();
    }

    list.add(uid<<8 | rating);
    movieToCust.put(mid, list);

    int sum = sumByMovie.get(mid);
    sumByMovie.put(mid, sum + rating);

}


/**
 * Adds an entry to the custToMovie hashtable. The
 * mid and rating are packed into one int to 
 * conserve memory. 
 *
 * @param  mid  The movie id. 
 * @param  uid  The user id. 
 * @param  rating  User uid's rating for movie mid.
 */
public void addToCust(int mid, int uid, int rating) {

    IntArrayList list;

    if(mid == 0 && uid == 0)
        return;

    if(custToMovie.containsKey(uid))
        list = (IntArrayList) custToMovie.get(uid);
    else
        list = new IntArrayList();

    list.add(mid<<8 | rating);
    custToMovie.put(uid, list);

    int sum = sumByCust.get(uid);
    sumByCust.put(uid, sum + rating);
}


/**
 * Sorts each entry in the movieToCust and 
 * custToMovie hashes to allow for efficient
 * searching. 
 */
public void sortHashes() {
    Sorter sorter = new Sorter();
    movieToCust.forEachPair(sorter);
    custToMovie.forEachPair(sorter);
}


/**
 * This class is used with the forEachPair method
 * of an OpenIntObjectHashMap when the Object is 
 * an IntArrayList. The apply method sorts the 
 * IntArrayList in ascending order. 
 */
private class Sorter implements IntObjectProcedure{

    /**
     * Sorts the IntArrayList in ascending order. 
     *
     * @param  first  uid or mid
     * @param  second IntArrayList of ratings. 
     * @return true
     */
    public boolean apply(int first, Object second) {
        IntArrayList list = (IntArrayList) second;
        list.trimToSize();
        list.sortFromTo(0, list.size() -1);
        return true;
    }
}


public static void main(String args[]){

    MemReader reader = new MemReader();

    String sourceFile = null;
    String destFile = null;

    try {
        sourceFile = args[0];
        destFile = args[1];

        reader.readData(sourceFile);
        reader.sortHashes();


        IntArrayList users = reader.custToMovie.keys();

        for(int i = 0; i < users.size(); i++) {
            System.out.println(users.get(i));
        }


        serialize(destFile, reader);


    }
    catch(Exception e) {
        System.out.println("usage: java MemReader sourceFile destFile");
        e.printStackTrace();
    }
}

} 以下是我将使用的示例数据:

 user movie rating
 1       1      5
 1       2      3
 1       10     3
 1       32     4
 1       34     4
 1       47     3
 1       50     4
 1       62     4
 1       150    4
 1       153    3
 1       160    3
 1       161    4
 1       165    4
 1       185    3
 1       208    3
 1       253    3
 1       265    5
 1       266    3
 1       288    5
 1       292    4
 1       296    5
 1       300    5

这是我得到的错误。任何帮助将不胜感激。我确信这是一件我想念的小东西,只需要一双新鲜的眼睛。问候。

java.lang.NumberFormatException: For input string: "user,movie,rating"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at memreader.MemReader.readData(MemReader.java:73)
at memreader.MemReader.main(MemReader.java:259)

4 个答案:

答案 0 :(得分:5)

您正在阅读第一行,其中不包含任何数字。您的文件也不是用逗号分隔的。你为什么用逗号分开?按空格分割

答案 1 :(得分:0)

if(in.hasNext()) in.nextLine();循环之前添加while以跳过第一行。

答案 2 :(得分:0)

第一行是“用户,电影,评级”分割后你将获得所有字符串而不是int,所以你需要跳过第一行。在while循环之前添加in.nextLine()以跳过第一行

答案 3 :(得分:0)

看起来您已包含所需的输出,而不是以逗号分隔的Inout。请注意,Integer.parseInt()Float.parseFloat()Double.parseDouble()等在无法解析输入时会抛出NumberFormatException(运行时)。它希望输入为Integer

在开始while循环之前,要么适当地捕获它,要么使用in.nextLine()跳过包含标题的第一行。这样做会在开始解析数字之前将扫描仪移动到第二行。