Эта проблема не просто дедупликация: это форма канонизации.
Стандартный подход заключается в использовании Map
вместо Set
. Вот эскиз, как это сделать:
public <T> List<T> canonicalizeList(List<T> input) {
HashMap<T, T> map = new HashMap<>();
List<T> output = new ArrayList<>();
for (T element: input) {
T canonical = map.get(element);
if (canonical == null) {
element = canonical;
map.put(canonical, canonical);
}
output.add(canonical);
}
return output;
}
Обратите внимание, что это O(N)
. Если вы можете с уверенностью предположить, что процент дубликатов в input
, вероятно, будет небольшим, тогда вы можете установить емкость map
и output
равной input
.
Теперь вы, кажется, говорите, что делаете это уже так (последний абзац), и вы спрашиваете, есть ли лучший способ. Насколько я знаю, нет ни одного. (API HashSet
позволяет вам проверять, содержит ли набор значение, равное element
, но не позволяет вам выяснить, что это за O(1)
.)
Для чего это стоит, под капотом класс HashSet<T>
реализован как HashMap<T, T>
. Таким образом, вы бы не экономили время и пространство, используя HashSet
напрямую ...