Java HashMap不能用循环初始化?从文本文件初始化HashMap
我是java的初学者,我正在努力理解HashMaps是如何工作的。我想将其用于我的talk bot,以便它能够识别用户提出的问题: 比如说,, 键(字符串)是用户提问的类别,值(列表)是机器人将查找的问题 我的问题是,当我在控制台中查看我的输出时,它看起来像是工作的,但当我调用map.getKey()时,我并没有得到我期望的结果 如果有帮助的话,我正在使用Java1.8 我有一个包含以下内容的文本文件: “!”是类别Java HashMap不能用循环初始化?从文本文件初始化HashMap,java,file,hashmap,Java,File,Hashmap,我是java的初学者,我正在努力理解HashMaps是如何工作的。我想将其用于我的talk bot,以便它能够识别用户提出的问题: 比如说,, 键(字符串)是用户提问的类别,值(列表)是机器人将查找的问题 我的问题是,当我在控制台中查看我的输出时,它看起来像是工作的,但当我调用map.getKey()时,我并没有得到我期望的结果 如果有帮助的话,我正在使用Java1.8 我有一个包含以下内容的文本文件: “!”是类别 !first! 1good 1hello 1bye !second! 2goo
!first!
1good
1hello
1bye
!second!
2good
2hello
2bye
这是我的测试类文件,包含以下代码:
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class InitHash
{
public static void main(String[] args)
{
File file = new File(System.getProperty("user.dir") + "/data.txt");
Map<String, List<String>> map = new HashMap<String, List<String>>();
try
{
Scanner scan = new Scanner(file);
String key = "";
List<String> value = new ArrayList<String>();
while (scan.hasNextLine())
{
String line = scan.nextLine();
if (line.contains("!"))
{
key = line;
key = key.replaceAll("!", "");
value.clear();
} else
{
value.add(line);
}
System.out.println(key + " , " + value);
map.put(key, value);
}
scan.close();
System.out.println(map.get("first")); //This prints the second category
System.out.println(map.get("second"));
} catch (Exception e)
{
e.printStackTrace();
}
}
}
感谢您的帮助和解释,
提前谢谢 在循环中,而不是:
value.clear();
每当您发现一个新类别时初始化它,以便不修改以前的值的内容(因为两个键的列表共享内存地址,所以您只是将最后一个类别的值复制到所有以前的类别)。这将为添加元素的位置分配一个新地址:
value=newarraylist()
如注释中所述,每次确定密钥已更改时,都应使用ArrayList
的新实例,否则您只需对每个密钥重新使用相同的ArrayList
下面的示例演示了代码的修改版本,因此当代码检测到新密钥,并且前一个密钥不为空时,它会将密钥
映射到ArrayList
的当前实例
然后,它将创建一个ArrayList
的新实例,并将所有前面的值放入其中
File file = new File(System.getProperty("user.dir") + "/data.txt");
Map<String, List<String>> map = new HashMap<String, List<String>>();
try (Scanner scan = new Scanner(file);) {
String key = "";
List<String> value = new ArrayList<String>();
while (scan.hasNextLine()) {
String line = scan.nextLine();
if (line.contains("!")) {
if (!key.trim().isEmpty()) {
map.put(key, value);
System.out.println(key + " , " + value);
}
key = line;
key = key.replaceAll("!", "");
value = new ArrayList<String>();
} else {
value.add(line);
}
}
if (!key.trim().isEmpty() && !value.isEmpty()) {
map.put(key, value);
}
scan.close();
System.out.println(map.get("first")); //This prints the second category
System.out.println(map.get("second"));
} catch (Exception e) {
e.printStackTrace();
}
File File=new文件(System.getProperty(“user.dir”)+“/data.txt”);
Map Map=newhashmap();
尝试(扫描仪扫描=新扫描仪(文件);){
字符串键=”;
列表值=新的ArrayList();
while(scan.hasNextLine()){
String line=scan.nextLine();
如果(第行包含(!”){
如果(!key.trim().isEmpty()){
map.put(键、值);
System.out.println(键+“,”+值);
}
键=行;
key=key.replaceAll(“!”,“”);
值=新的ArrayList();
}否则{
增值(行);
}
}
如果(!key.trim().isEmpty()&&!value.isEmpty()){
map.put(键、值);
}
scan.close();
System.out.println(map.get(“first”);//这将打印第二个类别
System.out.println(map.get(“第二”);
}捕获(例外e){
e、 printStackTrace();
}
当新键以更简洁的方式出现时,可以重写现有代码,以使用Java 8方法创建ArrayList
的新实例
另外,最好使用try with resources
确保输入文件的扫描仪自动关闭
Map Map=newhashmap();
尝试(扫描仪扫描=新扫描仪(文件)){
字符串键=”;
while(scan.hasNextLine()){
String line=scan.nextLine();
如果(第行包含(!”){
键=行。替换(“!”,“”);
computeIfAbsent(key,k->newArrayList());
}否则{
map.get(key)、add(line);
}
System.out.println(key+”,“+map.get(key));
}
System.out.println(map.get(“first”);//这将打印第二个类别
System.out.println(map.get(“第二”);
}
输出:
first , []
first , [1good]
first , [1good, 1hello]
first , [1good, 1hello, 1bye]
second , []
second , [2good]
second , [2good, 2hello]
second , [2good, 2hello, 2bye]
[1good, 1hello, 1bye]
[2good, 2hello, 2bye]
地图中的每个条目都应该使用一个唯一的
列表实例
,否则,所有键都共享同一个列表实例
。我也认为只有把钥匙放在地图上,当钥匙被认为已经改变了,你的意思是我必须创建两个列表吗?我试图在键更改时将列表放入映射,但“first”键返回null。也许我完全弄错了。对不起,我的英语不是最好的。请查看张贴的示例。您应该只有一个ArrayList
的实例,但每次键更改时,您都应该创建一个新实例(并将其分配给值
),以便可以向其添加新值现在我明白了!非常感谢!
first , []
first , [1good]
first , [1good, 1hello]
first , [1good, 1hello, 1bye]
second , []
second , [2good]
second , [2good, 2hello]
second , [2good, 2hello, 2bye]
[1good, 1hello, 1bye]
[2good, 2hello, 2bye]