我有一个来自github项目的文本文件(所有有效英语单词的集合),看起来像words.txt
我的文本文件位于我项目的resources
文件夹下。
我还有一个从mysql中的表中获取的行列表。 我想要做的是检查每一行中的所有单词是否都是有效的英语单词,这就是为什么我将每一行与我文件中包含的单词进行比较。
这是我迄今为止所尝试过的:
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 )
等等
答案 0 :(得分:2)
您可以使用方法List#containsAll(Collection)
如果此列表包含该列表的所有元素,则返回true 指定的集合。
假设你有两个列表已经被列入 myListFromRessources 和 myListFromRessources ,那么你可以这样做:
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);
答案 1 :(得分:1)
您可以阅读words.txt
文件,将单词转换为小写,然后将单词放入HashSet
。
使用boolean contains(Object o)
或boolean containsAll(Collection<?> c);
方法比较每个单词。
时间 O(n)。
提示:不要在每个循环中读取文件。阅读文件非常慢。
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));
答案 2 :(得分:1)
你的代码不起作用的原因是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);
}
}