检查字符串是否包含在 java 中的文本文件中

check if a string is contained in a text file of words in java

我有一个来自 github 项目的文本文件(所有有效英文单词的集合),看起来像这样 words.txt

我的文本文件在我项目的 resources 文件夹下。

我还有一个从 mysql 中的 table 获得的行列表。 我想做的是检查每一行中的所有单词是否都是有效的英文单词,这就是为什么我将每一行与我的文件中包含的单词进行比较的原因。

这是我迄今为止尝试过的:

 public static void englishCheck(List<String> rows) throws IOException {
    ClassLoader classLoader = ClassLoader.getSystemClassLoader();
    int lenght, occurancy = 0;
    for ( String row : rows ){

       File file = new File(classLoader.getResource("words.txt").getFile());


       lenght = 0;

       if ( !row.isEmpty()  ){
           System.out.println("the row : "+row);
           String[] tokens = row.split("\W+");
           lenght = tokens.length;
           for (String token : tokens) {

               occurancy = 0;
               BufferedReader br = new BufferedReader(new FileReader(file));

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


                   if ((line.trim().toLowerCase()).equals(token.trim().toLowerCase())){
                       occurancy ++ ;

                   }
                   if (occurancy == lenght ){ System.out.println(" this is english "+row);break;}

               }

           }





       }

   }
}

这仅适用于第一行,之后我的方法循环遍历仅显示它们的行并忽略比较,我想知道为什么这不适用于我的行集,它也适用如果我像这样预定义我的列表 List<String> raws = Arrays.asList(raw1, raw2, raw3 ) 等等

你可以使用方法List#containsAll(Collection)

Returns true if this list contains all of the elements of the specified collection.

让我们假设你有两个列表 myListFromRessourcesmyListFromRessources 然后你可以做:

List<String> myListFromRessources = Arrays.asList("A", "B", "C", "D");
List<String> myListFromRessources = Arrays.asList("D", "B");

boolean myInter = myListFromRessources.containsAll(myListFromSQL);
System.out.println(myInter);
myListFromSQL = Arrays.asList("D", "B", "Y");
myInter = myListFromRessources.containsAll(myListFromSQL);
System.out.println(myInter);

您可以读取words.txt文件,将单词转换为小写,然后将单词放入HashSet

使用boolean contains(Object o)boolean containsAll(Collection<?> c);方法比较每个单词。 时间是 O(n).

TIP: Do not read file in every loop. Reading file is very very slow.

ClassLoader classLoader = ClassLoader.getSystemClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("words.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
List<String> wordList = new LinkedList<String>(); // You do not know word count, LinkedList is a better way.
String line = null;
while ((line = reader.readLine()) != null) {
  String[] words = line.toLowerCase().split("\W+");
  wordList.addAll(Arrays.asList(words));
}
Set<String> wordSet = new HashSet<String>(wordList.size());
wordSet.addAll(wordList);


// then you can use the wordSet to check. 
// You shold convert the tokens to lower case.
String[] tokens = row.toLowerCase().split("\W+");
wordSet.containsAll(Arrays.asList(tokens)); 

您的代码不起作用的原因是 occurancy 只能是 0 或 1。您可以通过遵循逻辑或通过调试器来查看。

如果您的 words.txt 文件不是太大,并且您有足够的可用 RAM,您可以通过在开始时将 words.txt 文件读入内存来加快处理速度。此外,您只需要调用 toLowerCase() 一次,而不是每次比较时。但是,请注意语言环境。只要您没有任何非英语字符,例如德语 eszett 或希腊语 sigma,下面的代码就应该可以工作。

public static void englishCheck(List<String> rows) throws IOException {
    final URI wordsUri;
    try {
        wordsUri = ClassLoader.getSystemResource("words.txt").toURI();
    } catch (URISyntaxException e) {
        throw new AssertionError(e); // can never happen
    }

    final Set<String> words = Files.lines(Paths.get(wordsUri))
            .map(String::toLowerCase)
            .collect(Collectors.toSet());

    for (String row: rows)
        if (!row.isEmpty()) {
            System.out.println("the row : " + row);
            String[] tokens = row.toLowerCase().split("\W+");
            if (words.containsAll(Arrays.asList(tokens)))
                System.out.println(" this is english " + row);
        }
}