【问题标题】:Java removing from HashMap and writing changes in fileJava 从 HashMap 中删除并在文件中写入更改
【发布时间】:2014-09-07 21:22:47
【问题描述】:

所以在这里我有代码,我有由文件中的单词组成的 HashMap,我正在添加单词并将它们写入文件并且它可以工作,但是当我出于某种原因使用我的删除函数时,这里没有做任何事情是代码:

  import java.io.BufferedWriter;
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.FileWriter;
  import java.util.HashMap;
  import java.util.Map;
   import java.util.Scanner;

   public class Main {
   public static File file = new File( C:\\Users\\N\\Desktop\\Newfolder\\Dictionary\\src\\nmishewa\\geekycamp\\dictionary\\bg_win1251.txt");
public static int value = 1;
private static Scanner input;
public static Scanner in = new Scanner(System.in);
public static Map<String, Integer> map = new HashMap<String, Integer>();

public static void main(String[] args) throws FileNotFoundException {
    readFile();
    System.out.println("Enter number of function wanted" + "\n1 to add"
            + "\n2 for searching by prefix" + "\n3 for deleting");
    int choice = in.nextInt();
    if (choice == 1) {
        System.out.println("enter words seprated by comma");
        String wd = in.next();
        add(wd);
    }
    if (choice == 2) {
        System.out.println("Enter prefix");
        String wd = in.next();
        prefixSearch(wd);
    }
    if (choice == 3) {
        System.out.println("ENTER word to delete");
        String wd = in.next();
        remove(wd);
    }

}

public static void readFile() throws FileNotFoundException {
    input = new Scanner(file);
    boolean done = false;

    int value = 1;

    while (input.hasNext()) {
        String word = input.next().toLowerCase();
        String[] line = word.split("[,\\s]+");
        for (int j = 0; j < line.length; j++) {
            map.put(line[j], value);
            value++;
            done = true;
        }
    }
    if (done == true) {
        System.out.println("Succes");
    }
}

public static void prefixSearch(String wd) {
    System.out.println("Enter prefix");
    String prefix = wd.toLowerCase();
    for (Map.Entry<String, Integer> key : map.entrySet()) {
        if (key.getKey().startsWith(prefix)) {
            System.out.println(key.getKey());
        }
    }

}

public static void add(String wd) {
    boolean done = false;
    String word = wd.toLowerCase();
    String[] line = word.split("[,\\s]+");
    for (int j = 0; j < line.length; j++) {
        if (!map.containsKey(line[j])) {
            map.put(line[j], value);
            value++;

            try {
                FileWriter fw = new FileWriter(file.getAbsoluteFile());
                BufferedWriter bw = new BufferedWriter(fw);
                bw.write(map.toString());
                bw.close();
                done = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            continue;
        }
    }

    if (done == true) {
        System.out.println("Success");
    }

}

public static void remove(String wd) {
    boolean done = false;
    String word = wd.toLowerCase();
    String[] line = word.split("[,\\s]+");
    for (int j = 0; j < line.length; j++) {
        for (Map.Entry<String, Integer> key : map.entrySet()) {
            if (key.getKey().equals(line[j])) {
                map.remove(key.getKey(), key.getValue());
                try {
                    FileWriter fw = new FileWriter(file.getAbsoluteFile());
                    BufferedWriter bw = new BufferedWriter(fw);
                    bw.write(map.toString());
                    bw.close();
                    done = true;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                continue;
            }
        }

    }
    if (done == true) {
        System.out.println("Succes");
    }

}

}

其他所有方法都可以正常工作,但请删除。循环是否有问题,也许使用更优化的方式或?

【问题讨论】:

  • 你为什么要遍历map中的所有条目。 map.remove 也只接受一个参数,这是关键。你可以尝试使用类似if(map.containsKey(line[j])) { map.remove(line[j]); .... } 的东西而不是for 循环。
  • 顺便说一句,您能否也发布一个示例文件内容。

标签: java for-loop file-io hashmap


【解决方案1】:

失败的原因是您试图在迭代条目时更改地图。与任何集合一样 - 如果您尝试在迭代时对其进行修改,您将获得 ConcurrentModificationException

此外,还有一个冗余的内部 for 循环(冗余是因为映射的全部目的是您在查找特定值时不必对其进行迭代),这意味着您将尝试在一次就足够的情况下多次覆盖文件。

public static void remove(String wd) {
    boolean done = false;
    String word = wd.toLowerCase();
    String[] line = word.split("[,\\s]+");
    for (int j = 0; j < line.length; j++) {
        map.remove(line[j]);
    }
    try {
        FileWriter fw = new FileWriter(file.getAbsoluteFile());
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(map.toString());
        bw.close();
        done = true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (done == true) {
        System.out.println("Success");
    }
}

【讨论】:

    【解决方案2】:

    我在您的代码中看到的问题如下:

    1. 您在定义文件时忘记了引号:

      public static File file = new File( C:\\Users\\N\\Desktop\\Newfolder\\Dictionary\\src\\nmishewa\\geekycamp\\dictionary\\bg_win1251.txt")

    应该是:

    public static File file = new File("C:\\Users\\N\\Desktop\\Newfolder\\Dictionary\\src\\nmishewa\\geekycamp\\dictionary\\bg_win1251.txt");
    
    1. map中的remove()函数只接收一个参数,就是要移除的entry的key,所以:

      map.remove(key.getKey(), key.getValue());

    应该是:

    map.remove(key.getKey());
    

    另外,由于您获得了地图的 entrySet,也许您应该考虑将 rename() 函数中的 key 变量重命名为 entry

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-28
      • 1970-01-01
      • 2015-02-17
      • 1970-01-01
      • 2011-12-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多