繁体   English   中英

如何在迭代时添加到作为HashMap值的ArrayList中?

[英]How to add to an ArrayList that is a HashMap value while iterating?

我有一个HashMap,键的值是ArrayList。 当我逐行读取文件时,我需要添加到属于该特定键的ArrayList中。 该文件可能有1行或1百万行,键名将为行(字符串),其值表示文件中出现的行号。

有人可以帮我吗? 另外,这种快速的时间复杂性明智吗? 如果不是,我该如何优化呢?

示例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>

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函数返回一个表示成功或失败的布尔值。 这就是为什么您得到错误。 您必须先将您的号码添加到列表中,然后再将列表放入地图中。 但是,您的代码中存在另一个问题。 您将一遍又一遍地向所有键添加相同的列表。

试试这个代码:

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++;
}

您的问题是数组列表上的add方法返回一个布尔值。

您正在尝试创建“一致性”应用程序,并且在Java中进行网络搜索以找到解决方案非常容易。 这个问题的其他答案很好地说明了这个问题。

关于您的复杂性问题,使用哈希键(其键是单词,其值是行号的数组列表)是完全可以的(并且应该具有接近最佳的复杂度,因为每个行处理都需要摊销固定的时间)。 但是,只要所有内容都适合内存,情况就是如此! 如果您的文字文件陷入了千百万的风潮,那么您可以使用中间文件,与一个良好的map-reduce框架保持一致。

您正在做的是向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++;
}

我认为这应该工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM