2011-11-02 27 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; 
     } 
    }