我有一个巨大的字符串列表(List<String>
),可能包含超过 10.000个独特元素(字符串),我需要多次引用此列表(可能超过 10.000 ,以查明列表是否包含某些元素。
例如:
/**
* The size of this list might be over 10.000.
*/
public static final List<String> list = new ArrayList<>();
<...>
/**
* The size of the 'x' list might be over 10.000, too.
*
* This method just does something with elements in the list 'x'
* which are not in the list 'list' (for example (!), just returns them).
*/
public static List<String> findWhatsNotInList(List<String> x) {
List<String> result = new ArrayList<>();
for (String s : x) {
if (list.contains(s))
continue;
result.add(s);
}
return result;
}
<...>
此方法取决于列表list
和x
的大小,可以执行几分钟,这太长了。
有没有办法加快这个过程? (完全替换List
后,请随意建议任何,并使用其他内容循环。)
编辑:尽管使用了List#contains
方法,但我可能需要使用List#stream
并执行除String#equals
之外的其他检查(例如startsWith
})。例如:
/**
* The size of this list might be over 10.000.
*/
public static final List<String> list = new ArrayList<>();
<...>
/**
* The size of the 'x' list might be over 10.000, too.
*
* This method just does something with strings in the list 'x'
* which do not start with any of strings in the list 'list' (for example (!), just returns them).
*/
public static List<String> findWhatsNotInList(List<String> x) {
List<String> result = new ArrayList<>();
for (String s : x) {
if (startsWithAny(s, list))
continue;
result.add(s);
}
return result;
}
<...>
/**
* Check if the given string `s` starts with anything from the list `list`
*/
public boolean startsWithAny(String s, List<String> sw) {
return sw.stream().filter(s::startsWith).findAny().orElse(null) != null;
}
<...>
编辑#2:一个例子:
public class Test {
private static final List<String> list = new ArrayList<>();
static {
for (int i = 0; i < 7; i++) {
list.add(Integer.toString(i));
}
}
public static void main(String[] args) {
List<String> in = new ArrayList<>();
for (int i = 0; i < 10; i++)
in.add(Integer.toString(i));
List<String> out = findWhatsNotInList(in);
// Prints 7, 8 and 9 — Strings that do not start with
// 0, 1, 2, 3, 4, 5, or 6 (Strings from the list `list`)
out.forEach(System.out::println);
}
private static List<String> findWhatsNotInList(List<String> x) {
List<String> result = new ArrayList<>();
for (String s : x) {
if (startsWithAny(s, list))
continue;
result.add(s);
}
return result;
}
private static boolean startsWithAny(String s, List<String> sw) {
return sw.stream().filter(s::startsWith).findAny().orElse(null) != null;
}
}
答案 0 :(得分:1)
你基本上都在问如何最好地重新发明轮子。
唯一合理的答案是:不要。
含义:您希望对“大数据”实施大规模搜索。我建议您改为研究Solr或ElasticSearch等框架。因为处理大量数据的唯一真正答案是利用“横向扩展”解决方案。做那个“你自己”是一项严肃的事业!
如果您的要求有可能“增长”并且需要更复杂的搜索 - 那么就花费精力来选择最佳匹配技术。而不是尝试构建 hard 构建的东西。
上述框架带来了一定的开销 - 但如果使用得当,他们可以掌握数TB的数据。作为单个开发人员,你所能提出的任何事情都无法与之接近。在你的路上,你很可能会重复每个人都犯的错误。或者,正如你所说,你拿起看到这些错误的工具并在几年前修复它们。