13

我想检查两个捆绑包是否相等,有没有办法做到这一点,而不是一键检查它们?

4

5 回答 5

31

这是测试两个 Bundle 是否相同的一种方法:

  • 检查它们的尺寸,如果它们不相等,请不要打扰
  • 如果两个值都是 Bundle 对象,则使用递归
  • 因为 key in 的值onecan be null,所以确保两个值都是null并且 key实际存在于two
  • 最后比较匹配键的值

代码:

public boolean equalBundles(Bundle one, Bundle two) {
    if(one.size() != two.size())
        return false;

    Set<String> setOne = new HashSet<>(one.keySet());
    setOne.addAll(two.keySet());
    Object valueOne;
    Object valueTwo;

    for(String key : setOne) {
        if (!one.containsKey(key) || !two.containsKey(key))
            return false;

        valueOne = one.get(key);
        valueTwo = two.get(key);
        if(valueOne instanceof Bundle && valueTwo instanceof Bundle && 
                !equalBundles((Bundle) valueOne, (Bundle) valueTwo)) {
            return false;
        }
        else if(valueOne == null) {
            if(valueTwo != null)
                return false;
        }
        else if(!valueOne.equals(valueTwo))
            return false;
    }

    return true;
}
于 2012-11-05T19:11:46.380 回答
9

我已经测试了Sam的答案,它包含一个缺陷。另外,我现在很喜欢 Kotlin,所以这是我的版本。

  • 再次,键集需要相同的大小
  • 键集需要具有相同的值
  • 如果两个值都被Bundle递归测试。
  • 否则测试相等的值(不要重新测试包)

代码:

fun equalBundles(one: Bundle, two: Bundle): Boolean {
    if (one.size() != two.size())
        return false

    if (!one.keySet().containsAll(two.keySet()))
        return false

    for (key in one.keySet()) {
        val valueOne = one.get(key)
        val valueTwo = two.get(key)
        if (valueOne is Bundle && valueTwo is Bundle) {
            if (!equalBundles(valueOne , valueTwo)) return false
        } else if (valueOne != valueTwo) return false
    }

    return true
}
于 2017-10-18T11:16:31.043 回答
6
private static boolean equalsBundles(Bundle a, Bundle b) {
        Set<String> aks = a.keySet();
        Set<String> bks = b.keySet();

        if (!aks.containsAll(bks)) {
            return false;
        }

        for (String key : aks) {
            if (!a.get(key).equals(b.get(key))) {
                return false;
            }
        }

        return true;
    }
于 2012-11-05T15:30:15.793 回答
1

为了处理:

  • 具有捆绑值的捆绑
  • 带有捆绑包值列表的捆绑包

我想出了这个:

private static boolean equalBundles(final Bundle left, final Bundle right) {
    if (!left.keySet().containsAll(right.keySet()) || !right.keySet().containsAll(left.keySet())) {
        return false;
    }

    for (final String key : left.keySet()) {
        final Object leftValue = left.get(key);
        final Object rightValue = right.get(key);
        if (leftValue instanceof Collection && rightValue instanceof Collection) {
            final Collection leftCollection = (Collection) leftValue;
            final Collection rightCollection = (Collection) rightValue;
            if (leftCollection.size() != rightCollection.size()) {
                return false;
            }
            final Iterator leftIterator = leftCollection.iterator();
            final Iterator rightIterator = rightCollection.iterator();
            while (leftIterator.hasNext()) {
                if (!equalBundleObjects(leftIterator.next(), rightIterator.next())) {
                    return false;
                }
            }
        } else if (!equalBundleObjects(leftValue, rightValue)) {
            return false;
        }
    }
    return true;
}

private static boolean equalBundleObjects(final Object left, final Object right) {
    if (left instanceof Bundle && right instanceof Bundle) {
        return equalBundles((Bundle) left, (Bundle) right);
    } else  {
        return left == right || (left != null && left.equals(right));
    }
}
于 2018-03-21T12:29:35.620 回答
-1

单线法:

 static boolean isEqualBundle(Bundle a, Bundle b) {
    return a == b || (a != null && b != null && a.keySet().equals(b.keySet()) && a.keySet().stream().allMatch(s -> Objects.equals(a.get(s), b.get(s))));
}

static boolean isDeepEqualBundle(Bundle a, Bundle b) {
    return a == b || (a != null && b != null && a.keySet().equals(b.keySet()) && a.keySet().stream().map(s -> new Pair<>(a.get(s), b.get(s))).allMatch(s -> s.first instanceof Bundle && s.second instanceof Bundle ? isDeepEqualBundle((Bundle) s.first, (Bundle) s.second) : Objects.equals(s.first, s.second)));
}

//测试用例

    final Bundle a = new Bundle(), b = new Bundle(), c = new Bundle(), d = new Bundle(), e = new Bundle(), f = new Bundle(), aa = new Bundle(), bb = new Bundle(), cc = new Bundle();
    a.putString("1", "A");
    b.putString("1", "A");
    c.putString("1", "C");
    d.putString("1", null);
    e.putString("1", null);
    f.putString("2", null);


    aa.putString("2", "A");
    aa.putBundle("2", a);
    bb.putString("2", "A");
    bb.putBundle("2", b);
    cc.putString("2", "C");
    cc.putBundle("2", c);

    boolean isEquals1 = isEqualBundle(a, b); //true
    boolean isEquals2 = isEqualBundle(a, c); //false
    boolean isEquals3 = isEqualBundle(d, e); //true
    boolean isEquals4 = isEqualBundle(d, f); //false
    boolean isEquals5 = isEqualBundle(aa, bb); //false
    boolean isEquals6 = isEqualBundle(aa, cc); //false
    boolean isEquals7 = isDeepEqualBundle(aa, bb); //true
    boolean isEquals8 = isDeepEqualBundle(aa, cc); //false
于 2020-09-21T07:06:30.820 回答