2011-11-02 89 views
2

我有2个android intent对象,可以作为URL持久化,然后重新水化回intent对象。我想知道什么是最有效的方法来比较任何2个意图对象,以确保他们最终解决相同的活动与相同的参数等。使用intent.filterEquals这样做,但它不包括额外。比较Android意图对象

目前我的equals方法的代码如下所示:

  Intent a = Intent.parseUri(this.intentUrl, 
        Intent.URI_INTENT_SCHEME); 

      Intent b = Intent.parseUri(other.intentUrl, 
        Intent.URI_INTENT_SCHEME); 
      if (a.filterEquals(b)) { 
       if (a.getExtras() != null && b.getExtras() != null) { 
        for (String key : a.getExtras().keySet()) { 
         if (!b.getExtras().containsKey(key)) { 
          return false; 
         } else if (!a.getExtras().get(key) 
           .equals(b.getExtras().get(key))) { 
          return false; 

         } 
        } 
       } 
       // all of the extras are the same so return true 
       return true; 
      } else { return false; } 

但有一个更好/更清洁的方式?

回答

3

这可能是最好的,至少在概念上。但是,我不认为你的算法涵盖了b有一个a没有的密钥的情况。

我会得到这两个值keySet()并运行一个equals(),以确认它们都具有相同的密钥。然后,遍历一个值并在值对上运行equals()

+0

好点。也许更简单的方法是检查每个keySet的大小是否相同?如果它们不具有相同的大小,那么它们就不一样了,如果它们具有相同大小的键集并且每个值都位于a == b或者它们不相同。看到你能想到的任何缺陷? – Ben

+0

@Ben:它会是'equals()',而不是'==',就像你原来的代码一样。否则,这应该工作。 – CommonsWare

+0

好耶,我使用伪代码:) – Ben

1

这是相当多的东西CommonsWare建议用本的代码结合的执行,而且还覆盖情况下要么a有演员和b没有或b有演员和a没有。通过添加缺少return语句,也条件群众演员比较数组

private boolean areEqual(Intent a, Intent b) { 
    if (a.filterEquals(b)) { 
     if (a.getExtras() != null && b.getExtras() != null) { 
      // check if the keysets are the same size 
      if (a.getExtras().keySet().size() != b.getExtras().keySet().size()) return false; 
      // compare all of a's extras to b 
      for (String key : a.getExtras().keySet()) { 
       if (!b.getExtras().containsKey(key)) { 
        return false; 
       } else if (!a.getExtras().get(key).equals(b.getExtras().get(key))) { 
        return false; 
       } 
      } 
      // compare all of b's extras to a 
      for (String key : b.getExtras().keySet()) { 
       if (!a.getExtras().containsKey(key)) { 
        return false; 
       } else if (!b.getExtras().get(key).equals(a.getExtras().get(key))) { 
        return false; 
       } 
      } 
     } 
     if (a.getExtras() == null && b.getExtras() == null) return true; 
     // either a has extras and b doesn't or b has extras and a doesn't 
     return false; 
    } else { 
     return false; 
    } 
} 
+1

看起来这个实现有一个bug。在第二个循环之后不应该返回true吗?另一件需要考虑的事情是在方法开始时检查a == b。这样,许多昂贵的测试可以被跳过。 – jebcor

2

提高在@aostiles'回答:

private boolean intentsAreEqual (Intent a, Intent b) 
    { 
     if (a.filterEquals(b)) { 
      if (a.getExtras() != null && b.getExtras() != null) { 
       // check if the keysets are the same size 
       if (a.getExtras().keySet().size() != b.getExtras().keySet().size()) return false; 
       // compare all of a's extras to b 
       for (String key : a.getExtras().keySet()) { 
        if (!b.getExtras().containsKey(key)) { 
         return false; 
        } 
        else if (a.getExtras().get(key).getClass().isArray() && b.getExtras().get(key).getClass().isArray()) { 
         if (!Arrays.equals((Object[]) a.getExtras().get(key), (Object[]) b.getExtras().get(key))) { 
          return false; 
         } 
        } 
        else if (!a.getExtras().get(key).equals(b.getExtras().get(key))) { 
         return false; 
        } 
       } 
       // compare all of b's extras to a 
       for (String key : b.getExtras().keySet()) { 
        if (!a.getExtras().containsKey(key)) { 
         return false; 
        } 
        else if (b.getExtras().get(key).getClass().isArray() && a.getExtras().get(key).getClass().isArray()) { 
         if (!Arrays.equals((Object[]) b.getExtras().get(key), (Object[]) a.getExtras().get(key))) { 
          return false; 
         } 
        } 
        else if (!b.getExtras().get(key).equals(a.getExtras().get(key))) { 
         return false; 
        } 
       } 
       return true; 
      } 
      if (a.getExtras() == null && b.getExtras() == null) 
      { 
       return true; 
      } 
      // either a has extras and b doesn't or b has extras and a doesn't 
      return false; 
     } 
     else 
     { 
      return false; 
     } 
    }