Вопрос о set в Java, как Set работает для различения повторяющихся элементов?

#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 класса, и набор не будет иметь уникальных значений.