相关链接:http://hi.baidu.com/gabe2008/blog/item/eb0448da41d14168d1164e6f.html
当我看到这个问题:Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
比较标准的说法:Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。
而我的研究生同学居然说,判断是否重复是由系统内部实现的,他一时半会儿无法理解一个类还须重写equals来判断是否重复。我解释得已经蛮清楚,大体说法,与上一致,但他只接受代码层次的解释,那我对于以前写的TreeSetTest这个类进行简单的修改,才发现,我本不应该拿TreeSet这么特殊的类进行打比方,虽然它也继续于Set接口。
Set<Cat> set = new TreeSet<Cat>();
Cat a = new Cat("Qi");
Cat b = new Cat("Qi");
代码到这里已经编译报错了?因为,TreeSet是排序的集合,被排序的元素必须实现Comparable接口,那么实现呗。事实上,这里是运行时出错(ClassCastException,而不是编译期的错误。如果TreeSet的构造方法原型内是这个造型:Comparable<? super T>,那么会在编译检错,而Arrays.sort(E, Comparator<? super T> c),那会是如果没有实现Comparator的对象当做排序器,那么编译出错。原本JDK可以使用 class TreeSet<E extends Comparable>,这样的话就能在编译时候做检查。这样的话,就有了矛盾:那些没实现Comparable但是靠Comparator的机制就不行了。
class Cat implements Comparable 接口,那么按eclipse系统提示,一律返回1,我重写了Cat中的equals方法,用来说明如果Cat的name是一样的话,就返回true,按照我的设想,此TreeSet添加这个元素的时候一定不成功,可是遍历以后,发现它还是添加了两个"Qi",检索才知道,原来TreeSet是用Comparable的方法compareTo的返回值,完整代代码如下:
import java.util.*;
public class TreeSetTest {
public static void main(String[] args) {
Set<Cat> set = new TreeSet<Cat>();
set.add(new Cat("Cat1"));
set.add(new Cat("Cat2"));
set.add(new Cat("Cat"));
set.add(new Cat("Cat"));
set.add(new Cat("Cat")); //无法被成功添加,因为compareTo的结果是0,Cat name相同
Iterator<Cat> it = set.iterator();
while(it.hasNext()){
System.out.println(it.next().name+":");
}
}
}
class Cat implements Comparable{
public String name;
public Cat(String name){
this.name = name;
}
public int compareTo(Object o) {
String name = ((Cat)o).name;
return this.name.compareTo(name);
}
}
这里我们走一个极端,把compareTo的方法返回值一律为return 0; 那么只会添加第一个元素。如以下代码所示:
import java.util.Iterator;
import java.util.TreeSet;
class Drink implements Comparable<Object>{
public String name;
public int compareTo(Object o){
return 0;
}
}
public class TreeSetDrink {
public static void main(String[] args) {
Drink one = new Drink();
Drink two = new Drink();
one.name = "Coffee";
two.name = "Tea"; //因为compareTo返回为0,添加不成功,当成重复元素。
TreeSet set = new TreeSet();
set.add(one);
set.add(two);
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(((Drink)iterator.next()).name); //输出只有Coffee
}
}
再就是想到Set另一个重要子类HashSet,这个集合类继承于Set接口,爷爷是Collection接口,与HashMap没有什么直系血缘关系。首先他接受一个参数的泛型,泛型的作用就是在编译期去严格检查输入类型,HashSet添加元素时,需要对这个泛型类的hashCode值进行判断,测试是否为重复元素,代码如下:
import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;
public class HashSetTest {
public static void main(String[] args) {
Set<Pig> hashset = new HashSet<Pig>();
hashset.add(new Pig("X"));
hashset.add(new Pig("Y"));
hashset.add(new Pig("X"));
Iterator<Pig> iterator = hashset.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next().name);
}
}
}
class Pig{
public String name;
public Pig(String name){
this.name = name;
}
public boolean equals(Object o){ //如果不重写,那么所有的new Pig都会被加入,因为hashCode的默认是每个对象惟一的,与equals继承与Object,eqauls在那个阶段与==无异
String name = ((Pig)o).name;
if(this.name.equals(name)){
return true;
}else
return false;
}
public int hashCode(){ //重复测试,首先测试hashCode值,如果一样,再测试equals结果。
return 0; //这里只是测试方便这么写了,事实上,如果这么写,是没有任何存储效率的。
}
}
分享到:
相关推荐
在第一种方法中,我们首先将列表转换为集合,通过比较集合的长度和原列表的长度来判断是否有重复元素。如果两者长度相等,那么列表中的元素就是唯一的;反之,如果长度不相等,就说明存在重复元素。例如: ```...
Set:元素不可以重复,是无序。p508 Set接口中的方法和Collection一致。 |--HashSet: 内部数据结构是哈希表 ,是不同步的。 如何保证该集合的元素唯一性呢? 是通过对象的hashCode和equals方法来完成对象唯一性的...
在Java编程中,处理数据集合时,我们常常会遇到去除重复元素的需求。这可能是为了保持数据的唯一性,或者为了优化存储和计算效率。本文将详细介绍如何在Java中去除重复元素,主要关注数组和列表这两种常见数据结构。...
在Python编程语言中,集合(Set)是一种特殊的数据结构,它包含了唯一且无序的元素。集合的概念类似于数学中的集合论,主要用于存储不重复的数据。集合的创建通常使用`set()`函数,传入一个列表(List)或其他可迭代...
在Java编程中,处理整型数组并删除其中的重复元素是一项常见的任务。这通常涉及到集合类的使用,比如HashSet或ArrayList,以及基本的数组操作。本文将深入探讨如何实现这个功能,同时提供一种可能的解决方案。 首先...
首先,set的特点是保持元素的唯一性,这意味着在set中不会有重复的元素。当你向set中插入一个元素时,如果该元素已存在,则插入操作会忽略该元素,从而保证了set中元素的唯一性。set自动将元素进行排序,默认是升序...
在`set`容器中,元素不能重复,且元素默认按照升序排列。 #### 三、共同点 1. **底层实现**:在C++ STL中,`map`和`set`都是基于红黑树(Red-Black Tree)实现的。红黑树是一种自平衡二叉查找树,能够保证树的高度...
- 检查数据结构中元素的数量,判断是否为重复元素。 - 可能还会包含一些错误处理和输出结果的代码。 4. **优化**: - **空间优化**:如果只需要知道是否有重复元素,而不是找出所有重复元素,可以使用boolean...
存在重复元素 II" 是 LeetCode 中的一道问题,主要涉及到了数组处理和滑动窗口的概念。这个问题的目标是检查给定的整数数组 `nums` 中是否存在两个不同的索引 `i` 和 `j`,使得它们的值相等 `nums[i] == nums[j]`,...
在这个例子中,我们使用`indexOf`和`lastIndexOf`来判断元素是否重复。需要注意的是,这里使用`iterator.remove()`而不是`list.remove()`来删除元素,这可以避免并发修改异常。 ### 三、使用HashSet特性去除重复...
Python中的集合(Set)是一种非常实用的数据结构,它在概念上类似于数学中的集合,用于存储不重复的元素。集合的特点是没有特定的顺序,且不允许有重复的元素。在Python中,集合是由哈希表(Hash Table)实现的,这...
- **判断元素存在性**:`in`和`not in`关键字可用于检查元素是否在集合中,如`if 2 in my_set:`。 - **集合的长度**:`len()`函数可以获取集合中元素的数量,如`length = len(my_set)`。 6. **集合的实际应用** ...
1. HashSet:这是最常用的Set实现,它不保证元素的顺序,允许使用null值,但不允许元素重复。HashSet内部使用哈希表来存储元素,因此添加、删除和查找操作的平均时间复杂度为O(1)。 2. TreeSet:TreeSet基于红黑树...
- **Set**:Set是无序且不包含重复元素的集合。它不支持索引访问,但提供了一种唯一性保证。常见的Set实现类有HashSet和TreeSet。 2. **retainAll方法的实现原理** - 对于`List`,`retainAll`方法的实现通常是...
1. **数据存储**:List允许元素重复,而Set不允许。List中的元素有顺序,可以通过索引访问,而Set中的元素没有固定的顺序。 2. **插入与查找效率**:由于Set基于哈希表,通常查找和插入操作比List快。List的插入和...
Set 集合是一种无序集合,不能存储重复元素。HashSet、LinkedHashSet 和 TreeSet 是 Set 集合的三个常用的实现类。HashSet 使用 Hash 表结构,查询速度快,但不保证元素的顺序。LinkedHashSet 继承了 HashSet,添加...
在编程领域,集合类型是一种非常基础且重要的数据结构,它用于存储一组不重复的元素。在本场景中,我们关注的是一个特定的集合类型——`IntSet`,它专门用于存储整型数值。`IntSet`通常以高效、无序且不允许重复的...
### 集合概述:set、List、Map #### 一、集合框架概述 ##### 1.1.1 容器简介 ...- **元素重复性**:是否允许重复元素? 通过对比不同集合类的特点和使用场景,可以帮助开发者更好地选择最适合项目需求的集合类型。
在Java编程语言中,HashSet是一种常用的集合类,它实现了Set接口,不包含重复元素,并且不保证元素的顺序。在给定的“CustomSet.zip”压缩包中,我们看到一个名为“CustomSet.java”的文件,这很可能是用户自定义的...