关于Java中的Set,它是如何工作的以区分重复元素的?

huangapple go评论64阅读模式
英文:

Question about set in java, how does Set works to distinct the duplicate elements?

问题

以下是翻译好的部分:

有人能否解释一下 Java 中的 Set 是如何工作的?以下是代码示例:

--------------------------------------------------

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/List?但不能区分数组?我以为它们都是按引用传递,都是对象,对吗?
英文:

Can anyone please explain to me how Set works in java? Code as following:


			 List&lt;Integer&gt; list = new ArrayList&lt;&gt;();
			 list.add(1);
			 list.add(2);
			 list.add(3);
			 List&lt;Integer&gt; list1 = new ArrayList&lt;&gt;();
			 list1.add(1);
			 list1.add(2);
			 list1.add(3);
			 Set&lt;List&lt;Integer&gt;&gt; set = new HashSet&lt;&gt;();
			 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&lt;int[]&gt; set1 = new HashSet&lt;&gt;();
			 set1.add(arr);
			 set1.add(arr1);
			 System.out.println(set1);

output:
[[1, 2, 3]]
[[I@7852e922, [I@6d06d69c]

My question is how does Set can distinct ArrayList/List? But cannot distinct array? I thought both are pass by reference and both are the object right?

答案1

得分: 0

当你向set<SomeClass>添加一个新对象时,它会调用SomeClass类上的equals()方法。如果返回false(即相同的值不存在),则将对象添加到集合中。

// 这里调用了AbstractList类的equals()方法,因为集合是List类型
Set<List<Integer>> set = new HashSet<>();
set.add(list);
set.add(list1); // 此时list.equals(list1)为true
// 这就是你获得唯一值的原因

---------------
// 而当你添加一个普通的数组,它只是一个普通的Java对象,将调用Object类上的equals()方法,该方法通过引用进行比较
// 这就是为什么你不会得到唯一值的原因

Set<int[]> set1 = new HashSet<>();
set1.add(arr);
set1.add(arr1);

此外,在Set<Employee>的情况下,其中employee是一个用户定义的类。如果我们不在Employee类中定义具有自定义规则的equals()方法,将会调用从Object类继承的equals()方法,这样集合将不会具有唯一值。

英文:

When you add a new object to a set&lt;SomeClass&gt;, it calls equals() method on SomeClass class. If it returns false (i.e same value doesn't exist), it adds the object to the set.

https://docs.oracle.com/javase/8/docs/api/java/util/AbstractList.html#equals-java.lang.Object-

// equals() method of AbstractList class is called here because the set is // of List type

Set&lt;List&lt;Integer&gt;&gt; set = new HashSet&lt;&gt;();
             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&#39;t get unique values

Set&lt;int[]&gt; set1 = new HashSet&lt;&gt;();
             set1.add(arr);
             set1.add(arr1);

Furthermore, in case of Set&lt;Employee&gt; where employee is a user defined class. If we don't define equals() method with custom rules in Employee class, inherited equals() method from Object class will be called and the set will not have unique values.

huangapple
  • 本文由 发表于 2020年9月10日 06:40:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/63820470.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定