У меня есть набор элементов, которые сериализуются в файл. Некоторые предметы могут полагаться на другие предметы, но круглые ссылки не допускаются. Таким образом, они должны быть сериализованы таким образом, что если A
полагается на B
, B
сначала сериализуется в файле.Как написать транзитивный компаратор, когда «равенство» подразумевает «порядок не имеет значения»?
я написал Comparator
, который использует reliesOn()
функцию, чтобы определить, если два элемента связаны между собой:
Collections.sort(itemsToSort, new Comparator<Item>() {
@Override
public int compare(Item first, Item second) {
boolean firstReliesOnSecond = reliesOn(first, second);
if (firstReliesOnSecond) {
return 1;
}
boolean secondReliesOnFirst = reliesOn(second, first);
if (secondReliesOnFirst) {
return -1;
}
return 0;
}
});
Это работает для некоторых случаев, но не все. При отладке очевидно, что сортировка основана на транзитивном характере Comparator
и, по понятным причинам, не сравнивает все возможные сочетания элементов.
Например, пять пунктов A
через E
, если:
A -> B
B -> E
C
D
E
Тогда один возможный порядок будет:
E, B, A, C, D
По крайней мере, E
предшествует B
и B
приходит до A
.
Однако на этапе сравнения (перефразируя как пример), что происходит, является то, что C
сравнивается с E
, возвращая 0
, потому что они не имеют никакого отношения. И затем C
сравнивается с B
, а также возвращается 0
.
И в результате алгоритм сортировки предполагает B = E
, что составляет не. (Несмотря на то, что я разорвал договор Comparator
.) Как я могу написать свой метод compare()
таким образом, чтобы обеспечить транзитивность?
Редактировать: Было указано, что я выполняю топологическую сортировку на направленном ациклическом графе. У меня есть воспоминания о моем курсе Data Structures. К счастью, у Википедии есть хороший алгоритм линейного времени для выполнения этого вида - я дам ему шанс.
Кстати, это не 'Компаратор', который предполагает B = E, это алгоритм сортировки. ('Comparator' содержит очень маленький код) – immibis
Вы правы - я полагаю, это комбинация алгоритма сортировки и контракт, который должен выполнять« Компаратор ». Я обновляю свою формулировку, спасибо! –
Можете ли вы получить доступ к связанным объектам «Элемента»? Есть ли как 'getParents()' или что-то в этом роде? – aioobe