2015-07-14 2 views
1

Основное отличие между Set и List состоит в том, что набор не допускает дубликатов. Итак, вместо List<Integer[]> Я пытаюсь создать Set<Integer[]> так, чтобы не было двух элементов. Но я получаю следующие результаты, когда я прочитал Set<Integer[]>Как переопределить метод equals массива?

[0, 4, 5] 
[3, 4, 1] 
[4, 5, 0] 
[0, 3, 6] 
[1, 3, 4] 
[1, 2, 7] 

Для моей реализации, [0, 4, 5] и считаются равными. Поэтому мой вопрос: есть ли способ переопределить метод равных Integer[], чтобы метод функции set add не позволял принимать как [0, 4, 5], так и ?

+5

Почему вы не используете 'Set >' или somesuch? Или, 'Set '? Вы привязаны к 'Integer []' по какой-либо причине? – nneonneo

+4

И нет, вы ** не можете ** переопределить 'equals' для массива. – nneonneo

+0

Существует аналогичный вопрос с ответом: http://stackoverflow.com/questions/12292513/how-to-overide-equals-for-array-in-java В этом примере они использовали примитивный тип, но вы можете использовать метод, который принимает массивы Object []. – lordoku

ответ

5

Короткий ответ: вы не можете. Нет никакого механизма, чтобы переопределить что-либо в классе массива вообще.

Вместо этого, пожалуйста, рассмотрите возможность использования альтернативного контейнера для ваших объектов.Вы можете использовать Set<Integer> для объектов, создавая Set<Set<Integer>>, так как вам кажется, что вы хотите делать сравнения без порядка.

Или, для более точной настройки, рассмотрите возможность использования собственного класса, который обертывает массив или задает и имеет, например, Set<MyIntegerBag>. Затем вы будете иметь полный контроль над используемой операцией сравнения.

6

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

Поэтому, как предлагает @nneonneo, правильная вещь - использовать что-то, кроме массива. Массивы по существу имеют порядок в своих элементах, что означает, что вы сражаетесь в гору, пытаясь использовать Set<Integer[]>. У вас есть три лучших варианта:

  1. использовать структуру данных, не имеющую определенный порядок, например, HashSet
  2. использовать структуру данных, которая делает сохранить свойственный порядок, такие как TreeSet или TreeMultiset in Guava
  3. Используйте пользовательский объект, который переопределяет сравнение .equals(), что wraps массив.

Тогда ваша цель набор будет Set<Set<Integer>> или Set<Multiset<Integer>> или Set<MyWrapper> в каждом случае, соответственно.


Я рекомендую против с использованием пользовательских Comparator из неупорядоченных массивов для ваших Set соображений производительности. Сортированная структура данных может проводить сравнение равенства в сравнении O (n) Integer, но в наивном случае несортированный должен иметь хотя бы O (n log n). Однако это решение будет работать, если вы по какой-то причине должны использовать массив. Это то, что я имел в виду под «тяжелой битвой» выше.

+0

Downvoter ... почему? – durron597

+0

Когда вы рекомендуете не использовать пользовательский 'Comparator', я предполагаю из контекста, что вы неявно ссылаетесь на пользовательский Comparator * несортированных массивов. * –

+0

@ AndyThomas да, это правильно – durron597

3

Используйте java.util.TreeSet со компаратором, который возвращает ноль для двух массивов, которые вы считаете равными, и в противном случае следует за любым согласованным правилом упорядочения.

В соответствии с T reeSet documentation «экземпляр TreeSet выполняет все сравнения элементов с помощью метода compareTo (или сравнения), поэтому два элемента, которые считаются равными этому методу, равны с точки зрения множества. набора хорошо определено, даже если его упорядочение не соответствует равным, оно просто не подчиняется общему контракту интерфейса Set. "

0

Один из способов, чтобы полностью сравнить против двух массивов состоит в использовании метода:

Integer[]arrayOne, arrayTwo; 
//Arrays get set with contents, etc. 
Arrays.equals(arrayOne, array2); 

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

Это связано с аналогичным вопросом: How to overide equals for array in Java? В этом примере они использовали метод, который использовал примитивные типы массивов, но вы можете использовать метод, который принимает Object [].

Смежные вопросы