Хранение массивов в наборе и избегание дубликатов

HashSet<String[]> boog = new HashSet<String[]>();
boog.add(new String[]{"a", "b", "c"});
boog.add(new String[]{"a", "b", "c"});
boog.add(new String[]{"a", "b", "d"});

в

[a, b, c]
[a, b, d]
[a, b, c]

, где повторяется [A, B, C] , поэтому функция хеша не работает должным образом. Как бы я переопределил хеш-метод для строковых массивов. Или в этом отношении, общий массив? Есть ли лучший способ достичь того, что я пытаюсь сделать?

25
задан Tim Cooper 20 September 2011 в 15:56
поделиться

2 ответа

«Лучшим способом» является использование коллекций. Используйте List вместо String[]:

Set<List<String>> boog = //...
boog.add(Arrays.asList("a", "b", "c"));
boog.add(Arrays.asList("a", "b", "c"));
boog.add(Arrays.asList("a", "b", "d"));

System.out.println(boog.size()); // 2

Редактировать

Если вам абсолютно необходимо использовать массивы в качестве ключей, вы можете создать прозрачную оболочку вокруг каждой клавиши и поместить ее на карте. Некоторые библиотеки помогут вам в этом. Например, вот как вы можете сделать Set<String[]> используя Trove :

Set<String[]> boog = new TCustomHashSet<String[]>(new ArrayHashingStrategy());

boog.add(new String[]{"a", "b", "c"});
boog.add(new String[]{"a", "b", "c"});
boog.add(new String[]{"a", "b", "d"});

System.out.println(boog.size()); // 2

//...
public class ArrayHashingStrategy extends HashingStrategy<Object[]> {

   public int computeHashCode(Object[] array) {
      return Arrays.hashCode(array);
   }

   public boolean equals(Object[] arr1, Object[] arr2) {
      return Arrays.equals(arr1, arr2);
   }
}        
26
ответ дан 28 November 2019 в 18:15
поделиться

На самом деле вы используете метод hashCode по умолчанию, возвращающий разные значения для всех ваших разных массивов!

Лучший способ решить эту проблему - использовать Collection (например, List или a Set) или для определения собственного класса-оболочки, например:

public class StringArray {
    public String[] stringArray;

    [...] // constructors and methods

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        for(String string : stringArray){
            result = prime * result + ((string == null) ? 0 : string.hashCode());
        }
    }
}

Этот класс на самом деле использует почти тот же метод hashCode, что и метод для List.

Теперь вы обрабатываете:

HashSet<StringArray> boog = new HashSet<StringArray>();
1
ответ дан 28 November 2019 в 18:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: