比较两个列表 - 寻找更快,更有效的方式

时间:2013-11-07 23:47:33

标签: java performance list

我正在寻找比较两个“列表”的更好方法。这个想法是:我有两个由字符串组成的列表。如果两个列表中的所有字符串匹配,则我的方法返回true。 I.E

  

List(1)=“foo,foo1,foo2,foo3”

     

List(2)=“foo,foo1,foo2,foo3”

当比较这两个列表时,如果所有字符串匹配,则该方法返回true。如果任何元素不匹配,则返回false。

我拥有(和工作)的代码是这样的:但是我只是想知道是否有人能想出更好的解决方案来解决这个问题?

private boolean match(Context messageContext, ContextRule contextRule) {
if(contextRule.getMessageContext().getUser().equals(ContextRuleEvaluator.WILDCARD)
    || (contextRule.getMessageContext().getUser().equals(messageContext.getUser()))) {
  if(contextRule.getMessageContext().getApplication().equals(ContextRuleEvaluator.WILDCARD)
      || (contextRule.getMessageContext().getApplication().equals(messageContext.getApplication()))) {
    if(contextRule.getMessageContext().getService().equals(ContextRuleEvaluator.WILDCARD)
        || (contextRule.getMessageContext().getService().equals(messageContext.getService()))) {
      if(contextRule.getMessageContext().getOperation().equals(ContextRuleEvaluator.WILDCARD)
          || (contextRule.getMessageContext().getOperation().equals(messageContext.getOperation()))) {
        return true;
      }
    }
  }
}

return false;

}

上下文

public interface Context {    
  public String getUser();      
  public void setUser(String user);      
  public String getApplication();      
  public void setApplication(String application);      
  public String getService();      
  public void setService(String service);      
  public String getOperation();      
  public void setOperation(String operation);
}

ContextRule

public interface ContextRule {
  public Context getMessageContext();      
  public int getAllowedConcurrentRequests();      
}

3 个答案:

答案 0 :(得分:1)

我认为通过一些重构和应用DRY,你的方法可以和其他任何方法一样工作:

Context类中移动匹配逻辑:

@Override
public boolean match(Context anotherContext) {
    return match(this.getUser(), anotherContext.getUser()) &&
            match(this.getApplication(), anotherContext.getApplication()) &&
            match(this.getService(), anotherContext.getService()) &&
            match(this.getOperation(), anotherContext.getOperation());
}

private boolean match(String thisString, String thatString) {
    return thisString.equals(WILDCARD) || thisString.equals(thatString);
}

然后使用它:

private boolean match(Context messageContext, ContextRule contextRule) {
    Context ruleContext = contextRule.getContext();
    return ruleContext.match(messageContext);
}

答案 1 :(得分:0)

列表实现会覆盖equals方法。

是否要求不使用此功能?

list1.equals(list2);

的Javadoc:

  

将指定对象与此列表进行比较以获得相等性。当且仅当指定的对象也是列表时,返回true,两个列表具有相同的大小,并且两个列表中的所有对应元素对都相等。 (如果(e1 == null?e2 == null:e1.equals(e2)),则两个元素e1和e2相等。)换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等。此定义确保equals方法在List接口的不同实现中正常工作

这将执行上面的前两个操作,并将每个元素.equals(...)方法调用到其他操作。因此,请确保已正确覆盖元素中的equals方法。

答案 2 :(得分:0)

你可以做什么(但它会增加不必要的对象创建):

private static boolean match(Context messageContext, ContextRule contextRule) {
  Context ruleContext = contextRule.getMessageContext();
  String[] interleaved = {
      ruleContext.getUser(), messageContext.getUser(), 
      ruleContext.getApplication(), messageContext.getApplication(),
      ruleContext.getService(), messageContext.getApplication(),
      ruleContext.getOperation(), messageContext.getOperation()};
  for (int i = 0; i < interleaved.length; i += 2) {
    if (!interleaved[i].equals(ContextRuleEvaluator.WILDCARD) && 
        !interleaved[i].equals(interleaved[i + 1]) {
      return false;
    }
  }
  return true;
}

有可能提出这方面的许多变种,但我认为利用list.equals()很难,因为你需要考虑WILDCARD ......

我只是用更简洁的形式重写原始支票,利用助手来减少冗余,例如。

private static boolean matchValue(String ruleValue, String messageValue) {
  return ruleValue.equals(ContextRuleEvaluator.WILDCARD) 
      || ruleValue.equals(messageValue);
}

private static boolean match(Context messageContext, ContextRule contextRule) {
  Context ruleContext = contextRule.getMessageContext();
  return matchValue(ruleContext.getUser(), messageContext.getUser())
      && matchValue(ruleContext.getApplication(), messageContext.getApplication())
      && matchValue(ruleContext.getService(), messageContext.getService())
      && matchValue(ruleContext.getOperation(), messageContext.getOperation());
  }
}