从文本文件创建的字典-contains()始终返回false

时间:2018-10-06 13:35:07

标签: java list file dictionary contains

我目前正忙于一所小型大学的作业,并且对我实现的字典类的contains()方法有一些麻烦-该方法始终返回false。该类如下所示:

public class LocalDictionary {
    private ArrayList<String> wordsSet;

    public LocalDictionary() throws IOException {
        String wordListContents = new String(Files.readAllBytes(Paths.get("words.txt")));

        wordsSet = new ArrayList<>();
        String[] words = wordListContents.split("\n");
        for (int i = 0; i < words.length; i++) {
            wordsSet.add(words[i].toLowerCase());
        }
    }

    public boolean contains(String word) {
        return wordsSet.contains(word.toLowerCase());
    }
}

可从https://raw.githubusercontent.com/dwyl/english-words/master/words_alpha.txt获得字典用来获取单词的“ words.txt”文件,但这是其外观的摘要:

zinked
zinkenite
zinky
zinkiferous
zinkify
zinkified
zinkifies
zinkifying
zinnia
zinnias
zinnwaldite
zinober
zinsang
zinzar
zinziberaceae

我确保“ words.txt”中包含的单词包含在“ wordsSet”中,但无法弄清楚为什么contains方法对出现在ArrayList中的单词返回false。

非常感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

在添加前修剪for循环中的每一行。该行中每个单词后面似乎都有一些多余的空间。

for (int i = 0; i < words.length; i++) {
    wordsSet.add(words[i].toLowerCase());
}

for (int i = 0; i < words.length; i++) {
    wordsSet.add(words[i].trim().toLowerCase());
}

可以使用wordsSet.get(1).length()进行验证。根据您的文件,第一行是'aa',但是它打印的是3而不是2,这是因为每个单词后面都有一个多余的空格,需要在添加到列表之前进行修剪。

您的contains()方法没有问题。

答案 1 :(得分:0)

尝试使用BufferedReader,我为我努力工作(我删除了一些没用的行)。在您使用时,您正在从文件读取所有字节,将有多余的字节。

public class LocalDictionary {
    private ArrayList<String> wordsSet = new ArrayList<>();

    public LocalDictionary() throws Exception {

        //dont forget to absolute path to here. click righ click to file and copy path
        File file = new File("C:\\Users\\higuys\\IdeaProjects\\try\\src\\words.txt");
        BufferedReader br = new BufferedReader(new FileReader(file));

        String line;
        while ((line = br.readLine()) != null)
            //trim and tolowercase and add to list.
            wordsSet.add(line.trim().toLowerCase());

    }

    public boolean contains(String word) {
        return wordsSet.contains(word.toLowerCase());
    }
}

答案 2 :(得分:0)

您的问题似乎是操作系统依赖的行分离器的错误处理,在这里

String[] words = wordListContents.split("\n");

在字典的字符串上保留多余的字符。并非所有操作系统都使用“ \ n”来分隔行,因此您应该编写代码以考虑到这一点。

一种选择是让Java告诉您要使用的行分隔符,然后使用它:

String lineSeparator = System.getProperty("line.separator");
String[] words = wordListContents.split(lineSeparator);

在我看来,最简单的方法是使用“文件”获取所有行,例如:

private List<String> wordsSet1;
private ArrayList<String> wordsSet2;

public TestDictionary(String path) throws IOException {
    // my code:
    wordsSet1 = Files.readAllLines(Paths.get(path));

通过使用文件readAllLines,您可以让Java选择正确的行分隔符。

将您的代码与我的代码进行比较:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import save.MyColorFoo;

public class TestDictionary {
    // public static final String TXT_PATH = "src/pkg1/words.txt";
    // TODO: change this to your correct path
    public static final String TXT_PATH = "words.txt";
    private List<String> wordsSet1;
    private ArrayList<String> wordsSet2;

    public TestDictionary(String path) throws IOException {
        // my code:
        wordsSet1 = Files.readAllLines(Paths.get(path));

        // his code
        String wordListContents = new String(Files.readAllBytes(Paths.get(path)));

        wordsSet2 = new ArrayList<>();
        String[] words = wordListContents.split("\n");
        for (int i = 0; i < words.length; i++) {
            wordsSet2.add(words[i].toLowerCase());
        }

    }

    public boolean myContains(String word) {
        return wordsSet1.contains(word.toLowerCase());
    }

    public boolean hisContains(String word) {
        return wordsSet2.contains(word.toLowerCase());
    }

    public static void main(String[] args) {
        try {
            TestDictionary testDictionary = new TestDictionary(TXT_PATH);

            String testWord = "zinky";
            System.out.println("My List contains \"zinky\":  " + testDictionary.myContains(testWord));
            System.out.println("His List contains \"zinky\": " + testDictionary.hisContains(testWord));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

如果不确定原始文本文件是否包含所有小写字母,然后需要降低它们,则可以使用Streams来帮助您完成此操作:

wordsSet1 = Files.readAllLines(Paths.get(path))
        .stream().map(s -> s.toLowerCase())
        .collect(Collectors.toList());