我正在阅读包含多列数据集的文本文件。我正在使用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)
答案 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()
跳过包含标题的第一行。这样做会在开始解析数字之前将扫描仪移动到第二行。