#java #arrays #list #set #hashset
#java #массивы #Список #set #hashset
Вопрос:
Может кто-нибудь, пожалуйста, объяснить мне, как Set работает в Java? Код следующим образом:
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
List<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
Set<List<Integer>> set = new HashSet<>();
set.add(list);
set.add(list1);
System.out.println(set);
int[] arr = new int[3];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
int[] arr1 = new int[3];
arr1[0] = 1;
arr1[1] = 2;
arr1[2] = 3;
Set<int[]> set1 = new HashSet<>();
set1.add(arr);
set1.add(arr1);
System.out.println(set1);
вывод:
[[1, 2, 3]]
[[I @7852e922, [I @6d06d69c]
Мой вопрос в том, как Set может различать ArrayList / список? Но не может различать массив? Я думал, что оба передаются по ссылке, и оба являются правильным объектом?
Комментарии:
1. Разница в том, как они определяют hashCode и equals.
2. Чтобы добавить к этому комментарию, массивы в Java не переопределяют
Object.hashCode
иObject.equals
и, следовательно, рассматривают только тот же экземпляр массива, который равен самому себе.3. Чтобы сказать это по существу: A и B можно отличить, если
!A.equals(B)
Ответ №1:
Когда вы добавляете новый объект в set<SomeClass>
, он вызывает equals()
метод в SomeClass
классе. Если он возвращает false (т. Е. такое же значение не существует), он добавляет объект в набор.
https://docs.oracle.com/javase/8/docs/api/java/util/AbstractList.html#equals-java.lang .Объект-
// equals() method of AbstractList class is called here because the set is // of List type
Set<List<Integer>> set = new HashSet<>();
set.add(list);
set.add(list1); //list.equals(list1) is true at this point
// This is the reason you got unique values
---------------
// whereas when you add a plain array which is just a plain java object, equals() // gets called on Object class which compares by reference
// This is the reason you don't get unique values
Set<int[]> set1 = new HashSet<>();
set1.add(arr);
set1.add(arr1);
Кроме того, в случае Set<Employee>
, где employee является определяемым пользователем классом. Если мы не определим метод equals() с пользовательскими правилами в классе Employee, будет вызван унаследованный equals()
метод из Object
класса, и набор не будет иметь уникальных значений.