Tim*_*092 0 java arrays oop object
我对使用对象没有经验,所以我真的很想输入一些信息。
我正在尝试从其中包含某些“不需要的单词”的列表中删除注释,这些评论和“不需要的单词”列表都在ArrayList对象中。
这在名为的类中FormHelper,该类包含comments作为ArrayList 的私有成员,该auditListArrayList在名为的成员函数中本地创建populateComments(),然后该成员函数调用此函数(如下)。PopulateComments()由构造函数调用,因此在FormHelper创建的实例时,此函数仅被调用一次。
private void filterComments(ArrayList <String> auditList) {
for(String badWord : auditList) {
for (String thisComment : this.comments) {
if(thisComment.contains(badWord)) {
int index = this.comments.indexOf(thisComment);
this.comments.remove(index);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
关于实现此方法的方式感觉不对,我还担心自己对ArrayList函数的使用效率低下。我的怀疑正确吗?
它不是特别有效。但是,找到更有效的解决方案并非易事。
让我们回到一个更简单的问题。
private void findBadWords(List <String> wordList, List <String> auditList) {
for(String badWord : auditList) {
for (String word : wordList) {
if (word.equals(badWord)) {
System.err.println("Found a bad word");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
假设wordList包含N单词并且auditList包含M单词。一些简单的分析将显示内部循环的执行N x M时间。该N因素是不可避免的,但该M因素令人不安。这意味着您需要检查的“坏”字越多,检查所需的时间也越长。
有一个更好的方法可以做到这一点:
private void findBadWords(List <String> wordList, HashSet<String> auditWords) {
for (String word : wordList) {
if (auditWords.contains(word))) {
System.err.println("Found a bad word");
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么这样更好?更好(更快)是因为HashSet::contains不需要一次检查所有审核词。实际上,在最佳情况下,它将不检查任何一个(!),而通常情况仅检查其中的一两个。(我不会讨论为什么,但是如果您想了解,请阅读哈希表上的Wikipedia页面。)
但是您的问题更加复杂。您正在String::contains测试每个注释是否包含每个坏词。那不是一个简单的字符串相等性测试(按照我的简化版本)。
该怎么办?
一种可能的解决方案是将注释分成单词数组(例如,使用String::split然后使用HashSet查找方法。):
这改变了代码的行为。(实际上,这是一个很好的方法:请阅读Scunthorpe问题!)您现在将只匹配审核词,因为它们是注释文本中的实际单词。
将字符串拆分为单词并不便宜。如果使用String::split它,则需要创建并使用一个Pattern对象来查找单词边界,为每个单词创建子字符串并将它们放入数组中。您可能可以做得更好,但这始终是不平凡的计算。
因此,真正的问题将是优化是否会奏效。那最终将取决于的价值M; 即您要查找的坏词数量。越大M,将注释分成单词并使用a HashSet进行测试的可能性就越大。
另一种可能的解决方案不涉及拆分注释。您可以采用审核词列表,并将其组装为一个正则表达式,如下所示: \b(word-1|word-2|...|word-n)\b。然后使用此正则表达式与一起Matcher::find在每个注释字符串中搜索不良词。性能将取决于Java平台中正则表达式引擎的优化能力。它具有比拆分更快的潜力。
我的建议是在开始之前对整个应用程序进行基准测试和分析。仅优化:
当基准测试表明进行此评论检查的请求的整体性能令人担忧时。(如果可以,请不要浪费时间进行优化。)
当分析表明此方法是性能热点时。(真正的热点很有可能位于其他地方。如果是这样,则应优化它们而不是使用此方法。)
请注意,假设您已经(足够)完成了您的应用程序并为其创建了一个现实的基准,然后再考虑进行优化。(过早的优化不是一个好主意……除非您真的知道自己在做什么。)
| 归档时间: |
|
| 查看次数: |
109 次 |
| 最近记录: |