[英]Quickest way to return list of Strings by using wildcard from collection in Java
如果您希望所有字符串都以序列开头,则可以将所有String添加到类似TreeSet的NavigableSet中,并获得subSet(text, text+'\')
将给您所有以text
开头的条目。此查询为O(log n )
如果希望所有的字符串都以序列结尾,则可以执行类似的操作,除了必须反转字符串。 在这种情况下,从反向字符串到正向字符串的TreeMap将是更好的结构。
如果要“ x * z”,则可以搜索第一组并与Map的值合并。
如果要包含“ x ”,则可以使用Navigable <String,Set <String >>,其中键是从第一个,第二个,第三个字符开始的每个String等。该值是一个Set,因为您可以获取重复项。 您可以进行类似结构开头的搜索。
这是一个自定义匹配器类,该类无需进行正则表达式即可进行匹配(它仅在构造函数中使用regex,以更准确地说明它)并支持通配符匹配:
public class WildCardMatcher {
private Iterable<String> patternParts;
private boolean openStart;
private boolean openEnd;
public WildCardMatcher(final String pattern) {
final List<String> tmpList = new ArrayList<String>(
Arrays.asList(pattern.split("\\*")));
while (tmpList.remove("")) { /* remove empty Strings */ }
// these last two lines can be made a lot simpler using a Guava Joiner
if (tmpList.isEmpty())
throw new IllegalArgumentException("Invalid pattern");
patternParts = tmpList;
openStart = pattern.startsWith("*");
openEnd = pattern.endsWith("*");
}
public boolean matches(final String item) {
int index = -1;
int nextIndex = -1;
final Iterator<String> it = patternParts.iterator();
if (it.hasNext()) {
String part = it.next();
index = item.indexOf(part);
if (index < 0 || (index > 0 && !openStart))
return false;
nextIndex = index + part.length();
while (it.hasNext()) {
part = it.next();
index = item.indexOf(part, nextIndex);
if (index < 0)
return false;
nextIndex = index + part.length();
}
if (nextIndex < item.length())
return openEnd;
}
return true;
}
}
这是一些测试代码:
public static void main(final String[] args) throws Exception {
testMatch("foo*bar", "foobar", "foo123bar", "foo*bar", "foobarandsomethingelse");
testMatch("*.*", "somefile.doc", "somefile", ".doc", "somefile.");
testMatch("pe*", "peter", "antipeter");
}
private static void testMatch(final String pattern, final String... words) {
final WildCardMatcher matcher = new WildCardMatcher(pattern);
for (final String word : words) {
System.out.println("Pattern " + pattern + " matches word '"
+ word + "': " + matcher.matches(word));
}
}
输出:
Pattern foo*bar matches word 'foobar': true
Pattern foo*bar matches word 'foo123bar': true
Pattern foo*bar matches word 'foo*bar': true
Pattern foo*bar matches word 'foobarandsomethingelse': false
Pattern *.* matches word 'somefile.doc': true
Pattern *.* matches word 'somefile': false
Pattern *.* matches word '.doc': true
Pattern *.* matches word 'somefile.': true
Pattern pe* matches word 'peter': true
Pattern pe* matches word 'antipeter': false
尽管这还远远不能投入生产,但它应该足够快,并且支持多个通配符(包括开头和结尾)。 但是,当然,如果您的通配符仅在末尾,请使用彼得的答案(+1)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.