简体   繁体   English

比较 2 组字符串

[英]Compare 2 Sets of Strings

I have one list of Objects, that I iterate, and I need to compare one property of the object which is a String, and if that String ends with any value of a Given array y must save this object to be used later.我有一个迭代的对象列表,我需要比较 object 的一个属性,它是一个字符串,如果该字符串以给定数组的任何值结尾,则必须保存此 object 以供以后使用。

I need a optimal way to this check, any help?我需要一个最佳的方法来检查,有什么帮助吗?

Here is a example of what i want to do.这是我想做的一个例子。


List<TObject> itemList;
List<TObject> resultItemList;
String[] aSufix;

for(TObject item : itemList){
   for(String sufix : aSufix){
     if(item.name.endsWith(sufix)){
       resultItemList.add(item);
       break;
     }
   }
}

I was thinking of using a stream().anyMatch to check, but I am worried about creating too many Instances of Stream to do the comparative.我正在考虑使用 stream().anyMatch 进行检查,但我担心创建太多 Stream 实例来进行比较。

The Lists we are talking about 100+ suffixes, and the list of objects to check about 5000.我们谈论的列表有 100 多个后缀,要检查的对象列表大约有 5000 个。

This is a hard problem, and it's not clear just how badly you need to optimize this.这是一个难题,尚不清楚您需要优化它有多严重。 I'm going to assume you need the heavy stuff.我假设你需要沉重的东西。

It's almost going to simplify your task and allow you to use libraries more easily to treat this as a problem about prefixes, not suffixes.它几乎可以简化您的任务,并允许您更轻松地使用库来将其视为前缀问题,而不是后缀问题。 So you'll need to reverse your strings, especially the suffixes.所以你需要颠倒你的字符串,尤其是后缀。

static String reverse(String s) { 
   return new StringBuilder(s).reverse().toString();
}

If the list of prefixes is a constant, you can offload the heavy performance work to regex compilation.如果前缀列表是一个常量,您可以将繁重的性能工作卸载到正则表达式编译。 This has slower setup time, but works faster on the objects to check.这具有较慢的设置时间,但在要检查的对象上工作得更快。

StringBuilder patternBuilder = new StringBuilder("^("); // match at the start only
boolean first = true;
for (String suffix : suffixes) {
  if(!first) patternBuilder.append('|');
  patternBuilder.append(Pattern.quote(reverse(suffix)));
}
Pattern pattern = Pattern.compile(patternBuilder.append(')').toString());

Then to check if a given string has one of the suffixes,然后检查给定字符串是否具有后缀之一,

boolean hasOneOfTheSuffixes = pattern.matcher(reverse(str)).find();

A fancier version of this would create a specialized CharSequence implementation to reverse the string lazily, to avoid having to scan for the whole suffix.一个更高级的版本将创建一个专门的 CharSequence 实现来懒惰地反转字符串,以避免必须扫描整个后缀。 I'd only use this if your strings are really long.如果你的字符串真的很长,我只会使用它。

You could rewrite the regex to look for a suffix instead of a prefix in the reversed string, but that'd play less to the regex engine's strengths, costing more time looking for matches that aren't going to happen but start midway through the string.您可以重写正则表达式以在反向字符串中查找后缀而不是前缀,但这对正则表达式引擎的优势的影响较小,会花费更多时间来查找不会发生但从字符串中途开始的匹配.

If the list of prefixes is not a constant, then you probably want a sorted list of them.如果前缀列表不是常量,那么您可能需要它们的排序列表。

List<String> prefixes = new ArrayList<>();
for (String suffix : suffixes) {
  prefixes.add(reverse(suffix));
}
Collections.sort(prefixes);

Then to test if a string has one of the given suffixes,然后测试一个字符串是否具有给定的后缀之一,

String reversed = reverse(str);
int index = Collections.binarySearch(prefixes, reversed);
if (index >= 0) return true; // the string *is* one of the suffixes
index = ~index - 1; // the prefix *before* where the string goes in lex order
return index >= 0 && reversed.startsWith(prefixes.get(index));
  // check if the prefix at that index matches

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM