不打印关键频率的递增 HashMap 值
Incrementing HashMap values for key frequency doesn't print
我目前正在做一个项目来计算文本文件中单词的出现频率。 driver 程序将单词放入 ArrayList 中(在将它们变为小写并删除空格之后),然后 FreqCount object 将 ArrayList 放入将处理频率操作的 HashMap 中。到目前为止,我可以获取 driver 来读取文本文件,将其放入 ArrayList,然后将其放入 HashMap。我的问题是 HashMap 节点不重复,所以我试图在每次看到单词时增加值。
Driver:
package threetenProg3;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.ArrayList;
public class Driver {
public static void main(String[] args) throws FileNotFoundException{
File in = new File("test.txt");
Scanner scanFile = new Scanner(in);
ArrayList<String> parsed = new ArrayList<String>();
while(scanFile.hasNext()) { //if this ends up cutting off bottom line, make it a do while loop
parsed.add(scanFile.next().toLowerCase());
}
for(int i = parsed.size()-1; i>=0; i--) { //prints arraylist backwards
System.out.println(parsed.get(i));
} //*/
FreqCount fc = new FreqCount(parsed);
System.out.println("\n Hashmap: \n");
fc.printMap();
scanFile.close();
}
}
频率计数:
package threetenProg3;
import java.util.HashMap;
import java.util.List;
public class FreqCount {
//attributes and initializations
private HashMap<String, Integer> map = new HashMap<String, Integer>();
//constructors
FreqCount(List<String> driverList){
for(int dLIndex = driverList.size()-1; dLIndex>=0; dLIndex--) { //puts list into hashmap
for(String mapKey : map.keySet()) {
if(mapKey.equals(driverList.get(dLIndex))) {
int tval = map.get(mapKey);
map.remove(mapKey);
map.put(mapKey, tval+1);
}else {
map.put(mapKey, 1);
}
}
}
}
//methods
public void printMap() {
for (String i : map.keySet()) { //function ripped straight outta w3schools lol
System.out.println("key: " + i + " value: " + map.get(i));
}
} //*/
}
文本文件:
ONE TWO ThReE FoUR fIve
six seven
EIGHT
NINE
TEN ELEVEN
ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE, ONE, ONE,
输出:
one,
one,
one,
one
one
one
one
one
one
one
one
one
one
one
one
one
one
eleven
ten
nine
eight
seven
six
five
four
three
two
one
Hashmap:
key: nine value: 1
key: one, value: 1
key: six value: 1
key: four value: 1
key: one value: 1
key: seven value: 1
key: eleven value: 1
key: ten value: 1
key: five value: 1
key: three value: 1
key: two value: 1
key: eight value: 1
据我所知,输出应该打印出按键频率的正确值。在此先感谢您的帮助!
您可以按如下方式更改 FreqCount
的定义:
FreqCount(List<String> driverList) {
for (int dLIndex = driverList.size() - 1; dLIndex >= 0; dLIndex--) {
String key = driverList.get(dLIndex);
if (map.get(key) == null) {
map.put(key, 1);
} else {
map.put(key, map.get(key) + 1);
}
}
}
此更改后的输出:
Hashmap:
key: nine value: 1
key: one, value: 3
key: six value: 1
key: four value: 1
key: one value: 15
key: seven value: 1
key: eleven value: 1
key: ten value: 1
key: five value: 1
key: three value: 1
key: two value: 1
key: eight value: 1
或者,
FreqCount(List<String> driverList) {
for (int dLIndex = driverList.size() - 1; dLIndex >= 0; dLIndex--) {
String key = driverList.get(dLIndex);
map.put(key, map.getOrDefault(key, 0) + 1);
}
}
Map#getOrDefault
returns 指定键映射到的值,如果此映射不包含键的映射,则为默认值。
你有几个问题。
FreqCount(List<String> driverList){
for(int dLIndex = driverList.size()-1; dLIndex>=0; dLIndex--) { //puts list into hashmap
if(map.get(driverList.get(dLIndex)) != null) {
int tval = map.get(driverList.get(dLIndex));
map.remove(driverList.get(dLIndex));
map.put(driverList.get(dLIndex), tval+1);
}else {
map.put(driverList.get(dLIndex), 1);
}
}
}
你正在做一些奇怪的 for 循环,试图遍历一个空的 Map。您需要检查地图中是否有该词的键,如果有,则将值加一个,如果没有,则添加值为 1 的新对。
并避免数字带有逗号或点(如果需要,您可以将其他字符添加到 replaceAll 作为参数的正则表达式中)
while(scanFile.hasNext()) { //if this ends up cutting off bottom line, make it a do while loop
String value = scanFile.next().toLowerCase();
value = value.replaceAll("[,.]", "");
parsed.add(value);
}
现在的输出是
one
one
one
one
one
one
one
one
one
one
one
one
one
one
one
one
one
eleven
ten
nine
eight
seven
six
five
four
three
two
one
Hashmap:
key: nine value: 1
key: six value: 1
key: four value: 1
key: one value: 18
key: seven value: 1
key: eleven value: 1
key: ten value: 1
key: five value: 1
key: three value: 1
key: two value: 1
key: eight value: 1
没有重复的单词,即使有逗号,每个单词的计数都正确
在我看来,最简单的方法是使用 Map.merge 方法。该方法采用先前的值并应用映射函数。在这种情况下,第二个值未被使用。第一个值用于替换现有值 + 1。因此您得到字符串出现的频率。
另请注意,我将 class 更改为使用 parse
方法 returns 地图。在 class 构造函数中进行大量计算是不合适的。
读入值后。
FreqCount fc = new FreqCount();
Map<String,Integer> map = fc.parse(parsed);
map.entrySet().forEach(System.out::println);
打印
nine=1
one,=3
six=1
four=1
one=15
seven=1
eleven=1
ten=1
five=1
three=1
two=1
eight=1
修改后class
class FreqCount {
// attributes and initializations
private Map<String, Integer> map =
new HashMap<>();
public Map<String, Integer> parse (List<String> driverList) {
for (String str : driverList) {
map.merge(str, 1, (v1,notUsed)->v1 + 1);
}
return map;
}
}
我目前正在做一个项目来计算文本文件中单词的出现频率。 driver 程序将单词放入 ArrayList 中(在将它们变为小写并删除空格之后),然后 FreqCount object 将 ArrayList 放入将处理频率操作的 HashMap 中。到目前为止,我可以获取 driver 来读取文本文件,将其放入 ArrayList,然后将其放入 HashMap。我的问题是 HashMap 节点不重复,所以我试图在每次看到单词时增加值。
Driver:
package threetenProg3;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.ArrayList;
public class Driver {
public static void main(String[] args) throws FileNotFoundException{
File in = new File("test.txt");
Scanner scanFile = new Scanner(in);
ArrayList<String> parsed = new ArrayList<String>();
while(scanFile.hasNext()) { //if this ends up cutting off bottom line, make it a do while loop
parsed.add(scanFile.next().toLowerCase());
}
for(int i = parsed.size()-1; i>=0; i--) { //prints arraylist backwards
System.out.println(parsed.get(i));
} //*/
FreqCount fc = new FreqCount(parsed);
System.out.println("\n Hashmap: \n");
fc.printMap();
scanFile.close();
}
}
频率计数:
package threetenProg3;
import java.util.HashMap;
import java.util.List;
public class FreqCount {
//attributes and initializations
private HashMap<String, Integer> map = new HashMap<String, Integer>();
//constructors
FreqCount(List<String> driverList){
for(int dLIndex = driverList.size()-1; dLIndex>=0; dLIndex--) { //puts list into hashmap
for(String mapKey : map.keySet()) {
if(mapKey.equals(driverList.get(dLIndex))) {
int tval = map.get(mapKey);
map.remove(mapKey);
map.put(mapKey, tval+1);
}else {
map.put(mapKey, 1);
}
}
}
}
//methods
public void printMap() {
for (String i : map.keySet()) { //function ripped straight outta w3schools lol
System.out.println("key: " + i + " value: " + map.get(i));
}
} //*/
}
文本文件:
ONE TWO ThReE FoUR fIve
six seven
EIGHT
NINE
TEN ELEVEN
ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE, ONE, ONE,
输出:
one,
one,
one,
one
one
one
one
one
one
one
one
one
one
one
one
one
one
eleven
ten
nine
eight
seven
six
five
four
three
two
one
Hashmap:
key: nine value: 1
key: one, value: 1
key: six value: 1
key: four value: 1
key: one value: 1
key: seven value: 1
key: eleven value: 1
key: ten value: 1
key: five value: 1
key: three value: 1
key: two value: 1
key: eight value: 1
据我所知,输出应该打印出按键频率的正确值。在此先感谢您的帮助!
您可以按如下方式更改 FreqCount
的定义:
FreqCount(List<String> driverList) {
for (int dLIndex = driverList.size() - 1; dLIndex >= 0; dLIndex--) {
String key = driverList.get(dLIndex);
if (map.get(key) == null) {
map.put(key, 1);
} else {
map.put(key, map.get(key) + 1);
}
}
}
此更改后的输出:
Hashmap:
key: nine value: 1
key: one, value: 3
key: six value: 1
key: four value: 1
key: one value: 15
key: seven value: 1
key: eleven value: 1
key: ten value: 1
key: five value: 1
key: three value: 1
key: two value: 1
key: eight value: 1
或者,
FreqCount(List<String> driverList) {
for (int dLIndex = driverList.size() - 1; dLIndex >= 0; dLIndex--) {
String key = driverList.get(dLIndex);
map.put(key, map.getOrDefault(key, 0) + 1);
}
}
Map#getOrDefault
returns 指定键映射到的值,如果此映射不包含键的映射,则为默认值。
你有几个问题。
FreqCount(List<String> driverList){
for(int dLIndex = driverList.size()-1; dLIndex>=0; dLIndex--) { //puts list into hashmap
if(map.get(driverList.get(dLIndex)) != null) {
int tval = map.get(driverList.get(dLIndex));
map.remove(driverList.get(dLIndex));
map.put(driverList.get(dLIndex), tval+1);
}else {
map.put(driverList.get(dLIndex), 1);
}
}
}
你正在做一些奇怪的 for 循环,试图遍历一个空的 Map。您需要检查地图中是否有该词的键,如果有,则将值加一个,如果没有,则添加值为 1 的新对。
并避免数字带有逗号或点(如果需要,您可以将其他字符添加到 replaceAll 作为参数的正则表达式中)
while(scanFile.hasNext()) { //if this ends up cutting off bottom line, make it a do while loop
String value = scanFile.next().toLowerCase();
value = value.replaceAll("[,.]", "");
parsed.add(value);
}
现在的输出是
one
one
one
one
one
one
one
one
one
one
one
one
one
one
one
one
one
eleven
ten
nine
eight
seven
six
five
four
three
two
one
Hashmap:
key: nine value: 1
key: six value: 1
key: four value: 1
key: one value: 18
key: seven value: 1
key: eleven value: 1
key: ten value: 1
key: five value: 1
key: three value: 1
key: two value: 1
key: eight value: 1
没有重复的单词,即使有逗号,每个单词的计数都正确
在我看来,最简单的方法是使用 Map.merge 方法。该方法采用先前的值并应用映射函数。在这种情况下,第二个值未被使用。第一个值用于替换现有值 + 1。因此您得到字符串出现的频率。
另请注意,我将 class 更改为使用 parse
方法 returns 地图。在 class 构造函数中进行大量计算是不合适的。
读入值后。
FreqCount fc = new FreqCount();
Map<String,Integer> map = fc.parse(parsed);
map.entrySet().forEach(System.out::println);
打印
nine=1
one,=3
six=1
four=1
one=15
seven=1
eleven=1
ten=1
five=1
three=1
two=1
eight=1
修改后class
class FreqCount {
// attributes and initializations
private Map<String, Integer> map =
new HashMap<>();
public Map<String, Integer> parse (List<String> driverList) {
for (String str : driverList) {
map.merge(str, 1, (v1,notUsed)->v1 + 1);
}
return map;
}
}