我应该从文件中读取并计算单词总数,然后计算唯一单词的数量,例如对于前“我很高兴”有3个唯一单词...
我尝试使用HashMap进行此操作,但是在运行时出现错误,并且我认为本例不应该使用哈希表。有没有一种方法可以读取文件并仅使用array和ArrayList来计算唯一单词的数量? 错误:线程“主”中的异常java.lang.NullPointerException
这是我的使用哈希映射的代码,该代码无效:
public static void main(String[]args)throws IOException{
Scanner in = new Scanner(new File ("Lincoln.txt"));
int totalWords = 0;
while( in.hasNext()){
String word = in.next();
String[] spaces = word.split(" ");
String[] comma = word.split(",");
totalWords++;
}
System.out.println("The number of words are " + totalWords);
Map<String,Integer> words = new HashMap<String,Integer>();
countWords("D:\\Desktop\\CPS\\Lab11\\Lincoln.txt",words);
in.close();
}
public static void countWords(String filename,Map<String,Integer>words)throws FileNotFoundException{
Scanner file = new Scanner(new File(filename));
while(file.hasNext()){
String word = file.next();
int count = words.get(word);
if(count != 0){
count++;
}
else{
count =1;
words.put(word,count);
}
}
file.close();
}
答案 0 :(得分:0)
有没有一种方法可以读取文件并仅使用array和ArrayList计数唯一字符的数量?
您的问题令人困惑。首先,您谈论单词,然后跳到字符上。是哪一个?
如果我们回到80年代后期并认为我们生活在一个只有ASCII字符的世界中,就有可能用数组来计算唯一字符。
用数组或数组列表计数唯一单词,或在unicode世界中计数唯一字符……在丝毫,实际上不可能的情况下是不实际的(您当然可以做到这一点-但只能通过使用这些列表来手动笨拙地实现哈希图,或者编写一种效率极低的算法来做到这一点。
因此,我们仅假设您实际上打算为此使用地图。
此代码存在很多代码样式问题(例如,您重复Lincoln.txt,一次是相对的,一次是绝对路径),并且“单词数”计数器也被破坏了,因为您在空间(无用;扫描仪已经做到了)和逗号(有用)上进行了分割,但是对这些分割操作的结果却完全不执行任何操作。大概您想要totalWords += comma.length
。或者只是完全摆脱该方面,将“一个单词”定义为“用空格隔开的东西”,而不必考虑逗号。如果您不想忘记逗号,则希望更新扫描仪的定界符,并告诉扫描仪单词是空格或逗号之间的东西(scanner.useDelimiter("[ ,]+")
-的正则表达式是:定界符是任何序列1个或多个(空格或逗号)。
但是错误是这一行:
int count = words.get(word);
words开头是空的,这意味着words.get(word)
最初是在向地图询问与尚未在地图中的键关联的值。在这种情况下,get方法将返回null
。然后,将其分配给不能包含null的基元,因此java将通过对.intValue()
返回的值进行调用words.get(word)
来“自动取消装箱”您的值。然后,这会导致您观察到NullPointerException
,因为对空指针执行.foo
会这样做。您真正想要的是:“嘿,单词映射吗?请给我一个与键word
关联的Integer对象,但是如果您首先没有映射关系,那么不要返回null,而是,您可以返回0吗?谢谢!”。
哪些是可能和容易的?
int count = words.getOrDefault(word, 0);
请注意,如果尚未在映射中写入“ 1”,则在映射中写入“ 1”,但如果不存在,则不执行任何操作(count++
不会更改映射; java随处都按值传递。 count
是通过调用words.get(word)
获得的吗?它是副本。对其进行修改不会对该映射产生任何影响,您必须重新输入更新后的值。
如果您愿意,可以在一次合并中完成整个操作,但是这可能会超出您当前的水平。