简体   繁体   中英

MAP Problem with JAVA and Sqlite database

I have another question for you: The code below does the following

  1. For each file in a folder

  2. Open the file and read its contents

  3. Take and divide each line into tokens

  4. Save each token (word) in a hasMap

  5. Prepare a database query (Select form words ...)

  6. For each match found between the tokens and the words contained in the database Write 1.0, if true, otherwise 0.0;

The problem arises at this point :

try{
    while (rs_mail.next()) {
        if(result_m.contains(rs_mail.getString("voc_w").toString()))  //HERE I GET THE ERROR! java.lang.NullPointerException
            out_final.print("1.0;"); 
        else
            out_final.print("0.0;"); 
    }//Close While
}       //Close TRY
finally{
    rs_mail.close();
    //result_m.clear();
    mail.clear(); //Clear MAP
}

Below the complete code :

String path ="C:/Users/.../file";
File currentDIR = new File("C:/Users/.../file");
File files_mail[]=currentDIR.listFiles();
String tmp_mail="";

// prepares the file tmpTraning.txt to receive value 1.0, 0.0 obtained by comparison with database
PrintWriter out_final=null;
File ff=new File("C:/Users/.../tmpTraning.txt");

//Seach for File in DIR
for( File fX : files_mail ){
    String name_Filex = fX.getName();
    FileReader fr = null;
    BufferedReader fINx = null;
    String sx;
    //Create MAP 
    Map<String, Set<String>> mail = new HashMap<String, Set<String>>();
    //Open File
    try{
        Set<String> sq = new HashSet<String>();

        fr = new FileReader(path+"/"+name_Filex);
        fINx = new BufferedReader(fr);
        sx = fINx.readLine();

        //scroll the file
        while(sx != null) {
            StringTokenizer stq = new StringTokenizer(sx);
            while(stq.hasMoreTokens()) { //Extract form line the single word
                tmp_mail = stq.nextToken();

                sq.add(tmp_mail.toString().toLowerCase()); //add the word to sq -> HashMap
                mail.put(nome_Filex, sq);

            }// Close st.hasMoreTokens()

            sx = fINx.readLine();
        } //Close  while for scroll File
        fr.close(); //Close fileReader
        sq.clear(); //Clear HasSet

    } //Close il TRAY
    catch (FileNotFoundException ex) {
        ex.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    }

    Set<String> result_m = mail.get(name_Filex);
    ResultSet rs_mail = stmt.executeQuery("SELECT DISTINCT voc.words as voc_w FROM voc_words as voc");

    //Prepare for writing on the file " tmpTraning.txt " 
    OutputStreamWriter fout_f = new OutputStreamWriter(new FileOutputStream(ff,true));
    out_final = new PrintWriter(fout_f);

    try{
        while (rs_mail.next()) {
            //If the word extract from the database is in MAP (name_Filex) then print 1.0; on the file tmpTraning.txt
            if(result_m.contains(rs_mail.getString("voc_w").toString()))  //HERE I GET THE ERROR! java.lang.NullPointerException
                out_final.print("1.0;"); 
            else
                //else print 0.0;
                out_final.print("0.0;"); 
        }
    }       //Close TRY
    finally{
        rs_mail.close();
        //result_m.clear();
        mail.clear(); //Clear MAP
    }

    out_final.println(""); //Send CR char ASCII to set the coursor for the next file on the new line
    out_final.close();
    out_final.flush();
} // End SCAN DIR

Thanks for any advice!

Code changes - print the contents of result_m :

String path ="...";
File currentDIR = new File("...");
File files_mail[]=currentDIR.listFiles();
String tmp_mail="";

// prepares the file tmpTraning.txt to receive value 1.0, 0.0 obtained by comparison with database
PrintWriter out_final=null;
File ff=new File("...");

//Seach for File in DIR
for( File fX : currentDIR.listFiles() ){
    String name_Filex = fX.getName();

    String sx;
    //Create MAP 
    Map<String, Set<String>> mail = new HashMap<String, Set<String>>();
    //Open File
    try{
        Set<String> sq = new HashSet<String>();
        BufferedReader fINx = new BufferedReader(new FileReader(fX));
        sx = fINx.readLine();
        //scroll the file
        while(sx != null) {
            StringTokenizer stq = new StringTokenizer(sx);
            while(stq.hasMoreTokens()) { //Extract form line the single word
                tmp_mail = stq.nextToken();

                sq.add(tmp_mail.toString().toLowerCase()); //add the word to sq -> HashMap
                mail.put(name_Filex, sq);

            }// Close st.hasMoreTokens()

            sx = fINx.readLine();
        } //Close  while for scroll File
        fr.close(); //Close fileReader
        sq.clear(); //Clear HasSet

    } //Close il TRAY
    catch (FileNotFoundException ex) {
        ex.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    }

    /*
     * print the contents of  result_m
     */

    System.out.println("----- START FILE -----");
    Set<String> result_m = mail.get(name_Filex);
    Object[] toArray_m = mail.get(name_Filex).toArray();
    for (int ncc=0; ncc<result_m.size();ncc++){
        System.out.println(toArray_m[ncc]);
    }
    System.out.println("----- END  FILE  -----");


} // End SCAN DIR

if the file read by the program contains blank lines (no char, no string), it saves a null value

Is there a good reason that you are calling toString() on a string? If getString("voc_w") is null , then it will cause your exception.

As manji pointed out in the comment, it's either the call I mentioned, or the result_m Set that are null .

There are a great many issues with your code, unfortunately. Here's one that springs to my eye immediately.

You are using string manipulation to create the filename that you are passing in to the FileReader constructor, despite the fact that as far as I can see the file being opened is one returned from a listing of the directory. That's just asking for trouble. Instead, the code would be better off written more like this...

// Lots of things are omitted; this is just a sketch...
String path = "...";
File currentDIR = new File(path);
for (File fX : currentDIR.listFiles()) {
    try {
        BufferedReader fINx = new BufferedReader(new FileReader(fX));
        // ...
    } catch (IOException e) {
        e.printErrorStack();
    }
}

However, you have more problems than that. For example, the use of sq.clear() has bad code smell. You've just stowed a reference to that Set in the Map ; why are you deleting its contents again? The variable is falling out of scope; you can simply leave that code out. The down-stream consequences of that clear() are that result_m later on will be an empty set, so its contains test will always return false. I can't tell offhand whether that's the cause of your rogue null, but it's got to be wrong on the basis of what you're claiming to want to do.

Try refactoring that code into several smaller pieces that are easier to verify correct. I suggest as a first cut: a private method to get the Set of words from a File (supplied as argument), a private method to compare a Set of words against the database, and a method that combines those two with some looping to achieve your overall goal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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