如何在迭代时添加到作为 HashMap 值的 ArrayList?
How to add to an ArrayList that is a HashMap value while iterating?
我有一个 HashMap,键的值是一个 ArrayList。当我逐行读取文件时,我需要添加到属于该特定键的 ArrayList。
该文件可能有 1 行或 100 万行,键名将是行 (String),它的值将表示它在文件中出现的行号。
有人可以帮帮我吗?另外,这种快速的时间复杂性是否明智?如果不是,我该如何优化它?
示例test.txt:
Hello <== Line 0
Jello <== Line 1
Mello <== Line 2
Hello <== Line 3
Tello <== Line 4
Jello <== Line 5
Tello <== Line 6
Tello <== Line 7
我需要我的地图存储什么(忽略顺序):
{"Hello": [0, 3]}
{"Jello": [1, 5]}
{"Mello": [2]}
{"Tello": [4, 6, 7]}
我的代码是:
ArrayList<Integer> al = new ArrayList<Integer>();
Map<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>();
int num = 0;
for (String line = file.readLine(); line != null; line = file.readLine()) {
map.put(line, al.add(num)); <== the issue is here, how to fix?
}
编译器错误:
incompatible types: boolean cannot be converted to ArrayList<Integer>
你的问题是数组上的 add
方法列出了 returns 个布尔值。
您正在尝试做一个 "concordance" 应用程序,在 Java 中很容易在网络上搜索此问题的解决方案。这个问题的其他答案很好地说明了这一点。
关于您的复杂性问题,使用其键是单词且其值是行号数组列表的哈希图非常好(并且应该具有接近最佳的复杂性,因为每个行过程都需要摊销常数时间)。但是,只要一切都适合内存,情况就是如此!如果您的单词文件数量庞大,您可以使用中间文件与一个好的 map-reduce 框架进行索引。
Java 8:
map.computeIfAbsent(line, k -> new ArrayList<>()).add(num);
Java 7:
ArrayList<Integer> values = map.get(line);
if (values == null) {
map.put(line, values = new ArrayList<>());
}
values.add(num);
ArrayList的add函数returns一个布尔值,表示成功或失败。这就是您收到错误的原因。您必须先将您的号码添加到列表中,然后将列表放入地图中。但是您的代码中存在不同的问题。您将一遍又一遍地向所有键添加相同的列表。
试试这个代码:
Map<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>();
int currentLineNumber = 0;
for (String line = file.readLine(); line != null; line = file.readLine()) {
if(!hm.containsKey(line))
{
hm.put(line, new ArrayList<Integer>());
}
hm.get(line).add(currentLineNumber);
currentLineNumber++;
}
您正在做的是将整数添加到 HashMap 键而不是整个 ArrayList
尝试这样的事情:
Map<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>();
String key="";
while(file.readLine()!=null){
key=file.readLine();
ArrayList<Integer> al = new ArrayList<Integer>();
OUT: for (String line = file.readLine(); line != null; line = file.readLine()) {
if(key.equals(line)){
al.add(num);
}
else{
break OUT;
}
}
map.put(key, al);
}
此解决方案尚未经过测试,但我认为它会起作用。
Integer num = 0;
for (String line = file.readLine(); line != null; line = file.readLine()) {
if(!hm.containsKey(line))
{
hm.put(line, new ArrayList<Integer>());
}
hm.get(line).add(num);
num++;
}
我认为这应该可行。
我有一个 HashMap,键的值是一个 ArrayList。当我逐行读取文件时,我需要添加到属于该特定键的 ArrayList。 该文件可能有 1 行或 100 万行,键名将是行 (String),它的值将表示它在文件中出现的行号。
有人可以帮帮我吗?另外,这种快速的时间复杂性是否明智?如果不是,我该如何优化它?
示例test.txt:
Hello <== Line 0
Jello <== Line 1
Mello <== Line 2
Hello <== Line 3
Tello <== Line 4
Jello <== Line 5
Tello <== Line 6
Tello <== Line 7
我需要我的地图存储什么(忽略顺序):
{"Hello": [0, 3]}
{"Jello": [1, 5]}
{"Mello": [2]}
{"Tello": [4, 6, 7]}
我的代码是:
ArrayList<Integer> al = new ArrayList<Integer>();
Map<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>();
int num = 0;
for (String line = file.readLine(); line != null; line = file.readLine()) {
map.put(line, al.add(num)); <== the issue is here, how to fix?
}
编译器错误:
incompatible types: boolean cannot be converted to ArrayList<Integer>
你的问题是数组上的 add
方法列出了 returns 个布尔值。
您正在尝试做一个 "concordance" 应用程序,在 Java 中很容易在网络上搜索此问题的解决方案。这个问题的其他答案很好地说明了这一点。
关于您的复杂性问题,使用其键是单词且其值是行号数组列表的哈希图非常好(并且应该具有接近最佳的复杂性,因为每个行过程都需要摊销常数时间)。但是,只要一切都适合内存,情况就是如此!如果您的单词文件数量庞大,您可以使用中间文件与一个好的 map-reduce 框架进行索引。
Java 8:
map.computeIfAbsent(line, k -> new ArrayList<>()).add(num);
Java 7:
ArrayList<Integer> values = map.get(line);
if (values == null) {
map.put(line, values = new ArrayList<>());
}
values.add(num);
ArrayList的add函数returns一个布尔值,表示成功或失败。这就是您收到错误的原因。您必须先将您的号码添加到列表中,然后将列表放入地图中。但是您的代码中存在不同的问题。您将一遍又一遍地向所有键添加相同的列表。
试试这个代码:
Map<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>();
int currentLineNumber = 0;
for (String line = file.readLine(); line != null; line = file.readLine()) {
if(!hm.containsKey(line))
{
hm.put(line, new ArrayList<Integer>());
}
hm.get(line).add(currentLineNumber);
currentLineNumber++;
}
您正在做的是将整数添加到 HashMap 键而不是整个 ArrayList
尝试这样的事情:
Map<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>();
String key="";
while(file.readLine()!=null){
key=file.readLine();
ArrayList<Integer> al = new ArrayList<Integer>();
OUT: for (String line = file.readLine(); line != null; line = file.readLine()) {
if(key.equals(line)){
al.add(num);
}
else{
break OUT;
}
}
map.put(key, al);
}
此解决方案尚未经过测试,但我认为它会起作用。
Integer num = 0;
for (String line = file.readLine(); line != null; line = file.readLine()) {
if(!hm.containsKey(line))
{
hm.put(line, new ArrayList<Integer>());
}
hm.get(line).add(num);
num++;
}
我认为这应该可行。