Механизм наличия различных эквивалентов (физических и логических) для объектов в Коллекции.

Есть ли какой-либо механизм Equalator, такой как Comparator, чтобы я мог иметь разные равные для сопоставления списков?

EDIT: Моя цель состоит в том, чтобы различать текущий list1.equals(list2), который проверяет, является ли это поверхностной копией или также глубокой копией со всеми объектами a.equals(b) и list1.identical(list2) который проверяет, является ли это просто мелкой копией с неизмененным списком

Все эти списки от одной и той же модели. Некоторые из них являются копиями самих себя, поэтому содержат указатель на одни и те же объекты, а другие являются глубокими копиями, поэтому иерархия полностью реплицируется, потому что у них есть обновления в содержании, а не только в структуре.

Я часто делаю list1.equals(list2), но мне нужен механизм, чтобы определить, являются ли оба ПОЛНЫМИ копиями (одинаковые объекты в одном и том же порядке для коллекций) или иногда они являются ЛОГИЧЕСКИМИ копиями (через мою собственную реализованную логику equals), поэтому list будет вызывать equals, а объекты должны реализовывать нечто большее, чем a==b.

Моя проблема в том, что нет интерфейса эквалайзера, и если я переопределяю объекты равными, я теряю возможность сравнения по ВСЕМ РАВНЫМ (a==b)

Например, это было бы неплохо;

Collections.equal(l1,l2,new Equalator(){
    @Override public boolean equals(Obj1,Obj2){
          //Default lists comparison plus commparison of objects based on
          return (obj1.propertyX() == obj2.propertyX());
    }
});

и все же я мог бы сделать list1.equals(list2), чтобы они использовали равные по умолчанию (obj1 == obj2), и это было бы верно только в том случае, если бы содержащиеся объекты были точно такими же.

Первая операция полезна для проверки того, что список (который может быть обновленным списком с полностью воссозданными объектами из модели) по-прежнему равен старому списку.

Вторая операция полезна для проверки того, что список (который был неглубокой копией старой текущей версии модели данных) не содержит каких-либо трансцендентных изменений от перемещения внутри кода, когда он был обновленной версией.

EDIT: Очень хорошим примером может быть список Point(x,y). Мы должны быть в состоянии узнать, равны ли оба списка, потому что они представляют собой точно такой же набор точек, или равны, потому что точки, которые они содержат, равны логическим образом. Если бы мы могли реализовать как phyEqual, так и logEqual для объекта и иметь оба метода в любом объекте, то list.phyEqual(list2) или list1.logEqual(list2)


person Whimusical    schedule 01.08.2012    source источник
comment
У вас много контекста, но какой у вас на самом деле вопрос?   -  person Greg Kopff    schedule 01.08.2012
comment
Первая строка. Затем я определяю свою проблему. Извините, я начал с "есть ли" вместо "есть ли", и я думаю, что поэтому это сбивает с толку   -  person Whimusical    schedule 01.08.2012


Ответы (2)


Ваш вопрос не совсем понятен, по крайней мере мне. Если это не отвечает на него должным образом, не могли бы вы немного перефразировать?

В конкретном конкретном типе Collection большинство реализаций equals уже делают то, на что вы намекаете. Например:

    public boolean equals(Object o) {
        if (o == this)
            return true;

В этом случае что-то вроде этого может иметь смысл.
Вы можете легко переопределить это:

    @Override
    public boolean equals(Object o) {
        if (o.getPrimaryKey() == this.getPrimaryKey()) 
            return true;
        return super().equals(o);

[следует добавить тест на нулевые значения] Если вы создаете стандартные коллекции, вы даже можете анонимно переопределить метод equals во время создания.

Если это не делает то, что вы хотите, вы можете самостоятельно расширить коллекции и переопределить любой из методов, чтобы сделать то же самое.

Это помогает?

person JoeG    schedule 01.08.2012
comment
Список, по крайней мере, имеет равное значение, которое выглядит так, что оба списка имеют одинаковый размер, одинаковые элементы и одинаковый порядок. Проблема в том, что он использует equal для указания, одинаковы ли оба объекта, поэтому это означает, что без интерфейса эквалайзера мне нужно изменить всю структуру, чтобы иметь дополнительную цепочку равенств. Я могу реализовать равенство в своих объектах как логическое или физическое равенство, но тогда я не могу переключиться на другой тип - person Whimusical; 01.08.2012
comment
Существует очень мало реальных случаев, когда существует более одного определения равенства, которое действительно полезно для всех. - person Louis Wasserman; 01.08.2012
comment
Список. list.equals(list2), если оба имеют одинаковый размер, элементы и порядок (принимая во внимание, что элементы равны, если они удовлетворяют a.equals(b)). Но list.equals2(list2) может означать, что оба имеют одинаковый размер, элементы и порядок (принимая во внимание, что 2 obj равны, если a==b). Конечно, предполагая, что мы не можем гарантировать, что a.equals(b) не переопределен, поэтому не идет дальше, чем a==b - person Whimusical; 01.08.2012

Запоздалый ответ, но может кому пригодится...

Эквивалентность гуавы class для эквивалентности такой же, как Comparator для сравнения. Вам нужно будет написать свой собственный метод для сравнения списков (для этого нет поддержки в Guava), но тогда вы можете вызывать этот метод с различными определениями эквивалентности.

Или вы можете накатить свой собственный интерфейс:

interface Equalator<T> {
    boolean equals(T o1, T o2);
}

Опять же, вам нужно написать свой (тривиальный) метод

boolean <T> listEquals(List<T> list1, List<T> list2, Equalator<T> equalator) {
    ...  
}

... но затем вы можете повторно использовать его с различными реализациями ListEqualator.

person lbalazscs    schedule 26.02.2013