Набор, список и карта равенства сравнению с лямбды проверить


Я бы хотел, чтобы иметь возможность сравнивать два объекта с разными проверяет равенство. Это должно работать, если они в Set, List или Map Как хорошо.

Пример использования тестирования deserialzation сущности, которые могут содержать конфиденциальную информацию, как пароли, на серверной стороне, а не в ответ остальные.

Мне было бы интересно, если вы видите какие-либо недостатки конструкции или выявленных проблем.

Я также был бы благодарен за подсказку о существующих реализациях проектов мулине.

/**
 * Used by
 * {@link Tools#equals(java.lang.Object, java.lang.Object, EqualsCheck) }.
 *
 * @author richter
 */
@FunctionalInterface
public interface EqualsCheck<T> {

    boolean equals(T a, T b);
}

и методы:

/**
 * Does what
 * {@link java.util.Objects#equals(java.lang.Object, java.lang.Object) }
 * does, except allows to use methods to check equality as lambda.
 *
 * @param <T> allows to restrict the type of arguments to compare
 * @param a the first item
 * @param b the first item
 * @param equalsCheck the equality check to use
 * @return {@code true} if {@code a} and {@code b} are equal to each other,
 * {@code false} otherwise
 */
public static <T> boolean equals(T a, T b,
        EqualsCheck<T> equalsCheck) {
    return (a == b) || (a != null && equalsCheck.equals(a, b));
}

/**
 * Checks that all elements in {@code a} are contained in {@code b}.
 *
 * @param <T> allows to restrict the type of arguments to compare
 * @param a the first set
 * @param b the second set
 * @param equalsCheck the equality check to use
 * @return {@code true} if all elements in {@code a} are contained in
 * {@code b} and {@code b} contains no other items, {@code false} otherwise
 */
public static <T> boolean equalsSet(Set<T> a, Set<T> b,
        EqualsCheck<T> equalsCheck) {
    if(a == b) {
        return true;
    }
    if(a.stream().anyMatch(a0 -> b.stream().noneMatch(b0 -> equalsCheck.equals(a0, b0)))) {
        return false;
    }
    if(b.stream().anyMatch(b0 -> a.stream().noneMatch(a0 -> equalsCheck.equals(b0, a0)))) {
        return false;
    }
    return true;
}

/**
 * Checks that all elements in {@code a} are contained in {@code b} at the
 * same position.
 *
 * @param <T> allows to restrict the type of arguments to compare
 * @param a the first list
 * @param b the second list
 * @param equalsCheck the equality check to use
 * @return {@code true} if all elements in {@code a} are contained in
 * {@code b} at the same position and {@code b} contains no other elements,
 * {@code false} otherwise
 */
public static <T> boolean equalsList(List<T> a, List<T> b,
        EqualsCheck<T> equalsCheck) {
    if(a == b) {
        return true;
    }
    if(a.size() != b.size()) {
        return false;
    }
    Iterator<T> aItr = a.iterator();
    Iterator<T> bItr = b.iterator();
    while(aItr.hasNext()) {
        T aNxt = aItr.next();
        T bNxt = bItr.next();
        if(!equalsCheck.equals(aNxt, bNxt)) {
            return false;
        }
    }
    return true;
}

/**
 * Checks that all mappings between key and value in {@code a} are contained
 * in {@code b}.
 *
 * @param <K> allows to restrict the type of keys in both maps
 * @param <V> allows to restrict the type of values in both maps
 * @param a the first map
 * @param b the second map
 * @param equalsCheckKey the equality check to use for keys
 * @param equalsCheckValue the equality check to use for values
 * @return {@code true} if the key set of {@code a} and {@code b} is equals
 * as defined by
 * {@link #equalsSet(java.util.Set, java.util.Set, EqualsCheck) }
 * and all keys in {@code a} are mapped to the same values as they are in
 * {@code b}, {@code false} otherwise
 */
public static <K,V> boolean equalsMap(Map<K,V> a, Map<K,V> b,
        EqualsCheck<K> equalsCheckKey,
        EqualsCheck<V> equalsCheckValue) {
    if(a == b) {
        return true;
    }
    if(a.size() != b.size()) {
        return false;
    }
    if(!equalsSet(a.keySet(), b.keySet(), equalsCheckKey)) {
        return false;
    }
    for(K key : a.keySet()) {
        if(!equalsCheckValue.equals(a.get(key), b.get(key))) {
            return false;
        }
    }
    return true;
}


734
1
задан 15 марта 2018 в 01:03 Источник Поделиться
Комментарии
1 ответ

я думаю, что нет необходимости использовать Iterator для вас список сравнить, так как вы можете просто сравнить объекты внутри списка напрямую

boolean hasMismatch = IntStream.range(0,a.size()).allMatch(e -> a.get(e).equals(a.get(e)));

или, снова используя свой функциональности

boolean hasMismatch = IntStream.range(0,a.size()).allMatch(e -> equalsCheck.equals(a.get(e), b.get(e));

Примечание

richtercloud.project1.jar.controller интересное название пакета - может быть, вы можете найти что-то более подходящее

0
ответ дан 16 марта 2018 в 10:03 Источник Поделиться