使用 Google Guava 从用于索引的文件读取引起的 NullPointerException

NullPointerException caused by Reading from File used for indexing using Google Guava

我正在使用 Google Guava 来使用像这样的 Multimap,例如 {S1.E11=[S2.E236], S1.E108=[S2.E371]} 。但我有一个问题。我想从文件中读取映射实体并将它们放入我的 Multimap 中,这类似于使用哈希图进行索引。所以这是我的文件 mapping.csv:

S1.E10;S2.E235;0.86
S1.E108;S2.E371;0.99
S1.E109;S2.E372;0.99
S1.E11;S2.E236;0.86
S1.E113;S2.E51;0.73

这是我的 Java 代码:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package indexing;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

public class Indexing {

    public static String getKeyOfValue(String value, Multimap<String, String> multiM) {
        String keyOfValue = new String();
        Set<String> setKeys = multiM.keySet();
        for (String key : setKeys) {
            if (multiM.get(key).contains(value)) {
                keyOfValue = key;

            }
        }
        return keyOfValue;
    }

    public static boolean removeValueOfKey(String key, String value, Multimap<String, String> multiM) {
        Collection values = multiM.get(key);
        for (Iterator<String> iterator = values.iterator(); iterator.hasNext();) {
            String element = iterator.next();
            if (value.equals(element)) {
                values.remove(element);
                return true;
            }

        }
        return false;
    }
    /*e0 devient representant de e1*/

    public static void caseRptRpt(String e0, String e1, Multimap<String, String> multiM) {
        multiM.put(e0, e1);
        Collection values;
        //marquer e0 comme representant de e1
        values = multiM.get(e1);
        for (Iterator<String> iterator = values.iterator(); iterator.hasNext();) {
            String element = iterator.next();
            //marquer les representées par e1 comme represetées par e0
            multiM.put(e0, element);
        }
        //supprimer e1 des representants avec ses representées
        multiM.removeAll(e1);

    }

    public static void main(String[] args) throws IOException {

        // TODO code application logic here 
        Multimap<String, String> multiMap = ArrayListMultimap.create();
        BufferedReader br = new BufferedReader(new FileReader("mapping.csv"));
        String line = null;
        String[] tabLine;
        String[][] array = new String[5][5];
        try {
            while (((line = br.readLine()) != null)) {
                line = br.readLine();
                //line = line.trim();
                tabLine = line.split(";");
            //System.out.print(tabLine[0]);
                //System.out.print("  ");
                //System.out.println(tabLine[1]);

                if (!multiMap.isEmpty()) {
                    //si e0 est representant et e1 est  representant
                    if (multiMap.containsKey(tabLine[0]) && multiMap.containsKey(tabLine[1])
                            && !(multiMap.containsValue(tabLine[0]) || multiMap.containsValue(tabLine[1]))) {
                        //e1 devient representant de e0
                        caseRptRpt(tabLine[1], tabLine[0], multiMap);
                    } //si e0 est representant et e1 est representé par une entité e
                    else if (multiMap.containsKey(tabLine[0]) && multiMap.containsValue(tabLine[1])
                            && !(multiMap.containsValue(tabLine[0]) || multiMap.containsKey(tabLine[1]))
                            && !(multiMap.containsEntry(tabLine[0], tabLine[1]))) {
                        //marquer e1 comme representé par e0
                        multiMap.put(tabLine[0], tabLine[1]);
                        //supprimer e1 des representées par l'entité e
                        removeValueOfKey(getKeyOfValue(tabLine[1], multiMap), tabLine[1], multiMap);
                    } //sinon si e0 est representé par e et e1 est representant mais ne contient pas e0 comme representé
                    else if (multiMap.containsValue(tabLine[0]) && multiMap.containsKey(tabLine[1])
                            && !(multiMap.containsKey(tabLine[0]) || multiMap.containsValue(tabLine[1]))
                            && !(multiMap.containsEntry(tabLine[1], tabLine[0]))) {
                        //marquer e0 representé par e1
                        multiMap.put(tabLine[1], tabLine[0]);
                        removeValueOfKey(getKeyOfValue(tabLine[0], multiMap), tabLine[0], multiMap);
                    } // si e0 et e1 sont representées par des entitées diff 
                    else if (multiMap.containsValue(tabLine[0]) && multiMap.containsValue(tabLine[1])
                            && !(multiMap.containsKey(tabLine[0]) || multiMap.containsKey(tabLine[1]))
                            && !(getKeyOfValue(tabLine[0], multiMap).equals(getKeyOfValue(tabLine[1], multiMap)))) {
                        //marquer e0 comme representé par e1
                        multiMap.put(getKeyOfValue(tabLine[1], multiMap), tabLine[0]);
                        removeValueOfKey(getKeyOfValue(tabLine[0], multiMap), tabLine[0], multiMap);
                    } //else if (multiMap.isEmpty()) {
                    //multiMap.put(tabLine[0], tabLine[1]);
                    //}
                } else {
                    multiMap.put(tabLine[0], tabLine[1]);
                }

            }
        } catch (Exception e) {
            System.err.println("Error: " + e);
            e.printStackTrace();
        }
//to here
        System.out.println(multiMap);

    }

}

当我 运行 这就是我得到的 :

run:
Error: java.lang.NullPointerException
java.lang.NullPointerException
    at indexing.Indexing.main(Indexing.java:74)
{S1.E108=[S2.E371]}
BUILD SUCCESSFUL (total time: 0 seconds)

所以它似乎没有正确读取行或者我的长 if-else 语句中有问题,因此第二行为空。请问有什么帮助或建议吗?提前致谢。

为什么要在 while 循环中调用 readLine()?

        while (((line = br.readLine()) != null)) {
            line = br.readLine();

当您调用 readLine() 并且它不为空时,该行将被读入 line 变量。然后在 while 循环中,您将第二次调用 readLine()。第二次调用可能会导致 null(即流或文件的结尾)。