我正在寻找最有效的方法来获取List<String>
中包含一些String
值("value1"
)的所有元素。
首先想到 - 简单的迭代并将包含"value1"
的元素添加到另一个List<String>
但是这项任务必须经常由许多用户完成。
考虑list.RemoveAll()
,但如何删除所有不包含"value1"
的元素?
那么,什么方法可以最有效率?
更新
整体情况 - 需要经常从文件中读取日志,并同时为多个用户读取日志。必须使用文件中的用户名过滤日志。文件中的每个字符串都包含用户名。
答案 0 :(得分:2)
就时间效率而言,如果要遍历整个列表,则无法获得比线性(O(n)
)更好的结果。
在LinkedList
和ArrayList
等之间做出决定很可能无关紧要,因为差异很小。
如果你想要比列表大小更好的时间,你需要建立一些假设和先决条件:
如果您只有一个人输入的输入列表,并且您需要通读这一个输入并找到相关的字符串,那么您就会陷入线性时间,因为您无法避免在至少一次。
答案 1 :(得分:1)
根据您的评论,您的列表似乎是几个日志语句,应该按用户ID分组(这将是您的&#34; value1&#34;)。如果确实需要经常阅读日志,并且同时为多个用户阅读,您可能会考虑进行一些缓存,可能需要按用户ID进行分组。
作为示例,您可以为每个用户维护一个额外的日志文件,并在需要时显示它。通过使用一些按用户ID分组的FIFO缓冲区(可以是每个用户的缓冲区,也可能是另一个LIFO层),您可以将最新的日志语句保留在内存中。
但是,根据您的使用情况,可能不值得付出努力,您可能只是在用户请求时过滤列表。在这种情况下,我建议逐行读取文件,只将匹配的行添加到列表中。如果您首先将所有内容都读入单个列表然后删除不匹配的元素,那么效率会降低(您必须更频繁地迭代,转换元素等)并暂时使用更多内存(相反在检查之后立即丢弃每条不匹配的行。)
答案 2 :(得分:0)
而不是List
,使用提供TreeSet
的{{1}},以便所有字符串带有&#34; value1&#34;刚开始。迭代时,只要字符串不包含&#34; value1&#34;,其余所有字符串都没有,并且您可以停止迭代。
答案 3 :(得分:0)
迭代可能是唯一的方法,但您可以通过使用Java 8的流来允许Java尽可能地优化它(并使用优雅的非命令性语法):
// test list
List<String> original = new ArrayList<String>(){
{
add("value1");add("foo");add("foovalue1");add("value1foo");
}
};
List<String> trimmed = original
.stream()
.filter((s) -> s.contains("value1"))
.collect(Collectors.toList());
System.out.println(trimmed);
<强>输出强>
[value1, foovalue1, value1foo]
备注强>
"value1"
String
- 包含List
来尽早优化代码。
答案 4 :(得分:0)
好的,我可以建议你使用最简单的一个。 使用Iterator会更容易,但如果你使用list.remove(val),其中val =“value1”,可能会给你 UnsupportedOperationException
List list = yourList; / 包含“value1” /
for (Iterator<String> itr = list.iterator(); itr.hasNext();){
String val = itr.next();
if(!val.equals("value1")){
itr.remove();
}
}
试试这个,让我知道。 :)