为什么我的TreeMap将一个以'A'开头的键移动到keyValueSet的末尾?

时间:2018-01-18 02:47:00

标签: java

我目前正在制作一个方法,该方法会返回一个TreeMap<String, ArrayList<String>,其中包含definitions(key=term,value=definition)

出于某种原因,在我创建了该方法之后,它会在A的末尾添加一个以keySet开头的术语。我认为TreeMap在排序顺序中的位置?这只是所有其他项目的第一项。

真的很烦我,因为我无法看到我的bug在哪里。

主:

public static void main(String[] args)
{
    //Create new object
    FileParser fp = new FileParser();

    //call to method
    Map<String, ArrayList<String>> output = fp.createGlossary("glossary.txt");

    //print output
    for(Map.Entry<String,ArrayList<String>> entry : output.entrySet()) 
    {
        String key = entry.getKey();
        ArrayList<String> value = entry.getValue();

        System.out.println(key + " => " + value);
    }
}

方法:

public Map<String, ArrayList<String>> createGlossary(String fileName)
{
    //Local variables that are equal to a parsed file of terms and definitions
    ArrayList<String> termList = this.parseTerms(fileName);
    ArrayList<ArrayList<String>> defList = this.parsedDefinitions(this.rawDefinitions(fileName));

    //Map to to hold above variables
    Map<String, ArrayList<String >> glossary = new TreeMap<>();

    //Iterators to loop through the terms and definitions
    Iterator<String> termIterator = termList.iterator();
    Iterator<ArrayList<String>> defIterator = defList.iterator();
    System.out.println(glossary);


    //As both terms and definitions are the same length iterate until both are exhausted
    while(termIterator.hasNext() && defIterator.hasNext())
    {
        //put key-value pair using term as the key and definition as the value.
        String key = termIterator.next().toUpperCase();
        ArrayList<String> value = defIterator.next();
        glossary.put(key, value);
    }
    return glossary;
}

第一项和最后一项的输出:

//First Item in Map
ABSTRACT CLASS => [A, class, that, defines, a, common, message, protocol, and, common, set, of, instance, variables, for, its, subclasses., In, Java, an, abstract, class, cannot, be, instantiated.]

//Some K-V pairs from middle
SIGNATURE  => [See, method, signature.]
SOFTWARE => [A, general, term, for, all, programs, that, can, be, run, on, a, desktop, computer, or, another, hardware, platform,, such, as, a, mobile, phone.]
SOFTWARE COMPONENT => [A, piece, of, software, that, can, be, readily, combined, with, other, components, to, construct, more, complex, software.]
SORTED COLLECTION => [A, collection, that, always, keeps, its, elements, in, their, natural, ordering,, if, any., This, contrasts, with, an, ordered, collection,, where, the, ordering, may, just, be, an, accident, of, where, elements, happen, to, have, been, placed, in, the, collection.]
SOURCE CODE => [Program, text, expressed, in, a, high-level, programming, language.]
STABLE SORT => [A, sort, that, does, not, reorder, equal, elements.]

//Last Item in Map
ABSOLUTE PATHNAME => [A, full, path, to, a, file, beginning, from, the, name, of, the, storage, device.]

我没有复制所有内容,因为有数百行。但是,其他一切都是有序的吗?

这几乎就像它将ABSOLUTE PATHNAME推到了地图的末尾?

编辑:阅读评论后,我已经包括了课程,所以也许可以进行娱乐活动...... 方法readFileIn()只是一次读取每一行...如果该行是偶数,则有一个定义,如果该行是一个奇数,它是一个术语......希望足以重新创建bug。对于未注释的代码转储感到抱歉。

再次感谢。 保罗

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

public class FileParser 
{

private int numberOfTerms;

public void setNumberOfTerms(int numberOfTerms) { this.numberOfTerms = numberOfTerms; }

public ArrayList<String> readFileIn(String fileName)
{
    File file = new File(fileName);
    StringBuilder parsedFile = new StringBuilder();

    try
    {
        Scanner glossaryTXTFile = new Scanner(file);

        while (glossaryTXTFile.hasNextLine()) {
            String line = glossaryTXTFile.nextLine();
            parsedFile.append(line);
            parsedFile.append("\n");

        }
        glossaryTXTFile.close();
        parsedFile.setLength(parsedFile.length() - 1);

        return new ArrayList<>(Arrays.asList(parsedFile.toString().split("\n")));
    }
    catch (FileNotFoundException e)
    {
        System.out.println("File not found, please check the path and make sure extension is included.");
        e.printStackTrace();
        return null;
    }
}

public ArrayList<String> rawDefinitions(String fileName)
{
    ArrayList<String> definitions = new ArrayList<>();
    int counter = 1;
    for(String holder : this.readFileIn(fileName))
    {
        if(counter % 2 == 0)
        {
            definitions.add(holder);
        }
        counter++;
    }

    return definitions;
}
public ArrayList<ArrayList<String>> parsedDefinitions(ArrayList<String> sentence)
{

    ArrayList<ArrayList<String>> choppedSentences = new ArrayList<>();
    for(String words : sentence)
    {
        String[] splitSentences = words.split(" ");
        choppedSentences.add(new ArrayList(Arrays.asList(splitSentences)));
    }
    this.setNumberOfTerms(choppedSentences.size());
    return choppedSentences;
}
public ArrayList<String> parseTerms(String fileName)
{
    ArrayList<String> terms = new ArrayList<>();
    int counter = 1;
    for(String holder : this.readFileIn(fileName))
    {
        if(counter % 2 != 0)
        {
            terms.add(holder);
        }
        counter++;
    }
    return terms;
}
public Map<String, ArrayList<String>> createGlossary(String fileName)
{
    //Local variables that are equal to a parsed file of terms and definitions
    ArrayList<String> termList = this.parseTerms(fileName);
    ArrayList<ArrayList<String>> defList = this.parsedDefinitions(this.rawDefinitions(fileName));

    //Map to to hold above variables
    Map<String, ArrayList<String >> glossary = new TreeMap<>();

    //Iterators to loop through the terms and definitions
    Iterator<String> termIterator = termList.iterator();
    Iterator<ArrayList<String>> defIterator = defList.iterator();
    System.out.println(glossary);


    //As both terms and definitions are the same length iterate until both are exhausted
    while(termIterator.hasNext() && defIterator.hasNext())
    {
        //put key-value pair using term as the key and definition as the value.
        String key = termIterator.next().toUpperCase();
        ArrayList<String> value = defIterator.next();
        glossary.put(key, value);
    }
    return glossary;
}

public static void main(String[] args)
{
    //Create new object
    FileParser fp = new FileParser();

    //call to method
    Map<String, ArrayList<String>> output = fp.createGlossary("glossary.txt");

    //print output
    for(Map.Entry<String,ArrayList<String>> entry : output.entrySet())
    {
        String key = entry.getKey();
        ArrayList<String> value = entry.getValue();

        System.out.println(key + " => " + value);
    }
}

}

1 个答案:

答案 0 :(得分:2)

根据代码,我确信你的文本文件有一些不可见的字符,这会在Treemap排序中产生问题。

考虑以下示例,

public class App {

    public static void main(String[] args) {
        Map<String, List<Integer>> treeMap = new TreeMap<>();
        treeMap.put("ABSTRACT CLASS", Arrays.asList(1, 2, 3, 4));
        treeMap.put("\u200eABSOLUTE PATHNAME", Arrays.asList(11, 22, 33, 44));

        for (Entry<String, List<Integer>> entry : treeMap.entrySet()) {
            System.out.println(entry);
        }
    }
}

<强>输出

ABSTRACT CLASS=[1, 2, 3, 4]
‎ABSOLUTE PATHNAME=[11, 22, 33, 44]

确保您的文本文件包含正确的内容。要检查不可见的字符,您可以使用Notepad ++,只需打开文件并启用查看&gt;显示符号&gt;显示所有字符