`
lihengzkj
  • 浏览: 45063 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

关于SET元素不重复的实现

QQ 
阅读更多
set的实现类HashSet/TreeSet的底层实现是通过HashMap/TreeMap来实现的。Set的实现类在创建对象的时候都,在构造方法里面都是创建了一个Map的实现类来实现的。而Map中的元素是“键-值”对,其中“键”必须是唯一的。Set就是利用“键”唯一这个特性来实现元素不重复的。它把Set中的元素作为Map的键,从而保持了元素的唯一性。
public class TestTreeSet {
	public static void main(String [] args){
		Set set = new TreeSet();
		set.add(new Element1("aa"));
		set.add(new Element1("bb"));
		set.add(new Element1("aa"));
	}
}
class Element1{
	String s ;
	public Element1(String s){
		this.s = s;
	}
	@Override
	public String toString(){
		return s;
	}
	@Override  //这里重写了equals方法,但是实际是没有作用的。
	public boolean equals(Object obj) {
		return s.equals(((Element1)obj).s);
	}
}
// 报错:java.lang.ClassCastException: com.lovo.TestTreeSet$SetElement cannot be cast to java.lang.Comparable
//at java.util.TreeMap.put(TreeMap.java:542)
//at java.util.TreeSet.add(TreeSet.java:238)
//at com.lovo.TestTreeSet.main(TestTreeSet.java:10)
public class TestTreeSet2 {
	public static void main(String[] args) {
		Set set = new TreeSet();
		set.add(new Element2("ss"));
		set.add(new Element2("qq"));
		set.add(new Element2("ss"));
		System.out.println(set);
	}
}
class Element2 implements Comparable{
	   String s; 
	   public Element2(String s){ 
	    this.s =  s; 
	   } 
	   public String toString(){ 
	    return s; 
	   } 
	   public int compareTo(Object o){ 
	    return s.compareTo(((Element2)o).s); 
	   } 
	   public boolean equals(Object obj) { 
	    return s.equals(((Element2)obj).s); 
	   }
	}
/**
*运行结果:[qq, ss]  --达到我们想要的结果。
*TestTreeSet和TestTreeSet2唯一区别就是Element2实现了Comparable接口。进入TreeMap.java:542其实可以看到TreeSet在添加
*元素的时候是使用了TreeMap的put方法。而put方法的实现是通过实现接口Comparable中的CompareTo方法来实现的。所以TreeSet在添加元素
*的时候是把元素cast to Comparable,再来使用compareTo进行比较。
*综合:TreeSet是使用了CompareTo来实现集合中元素不重复。
*/
public class TestTreeSet3 {
	public static void main(String[] args) {
		Set set = new TreeSet();
		set.add(new Element3("ss"));
		set.add(new Element3("qq"));
		set.add(new Element3("ss"));
		System.out.println(set);
	}
}
class Element3 implements Comparable{
	   String s; 
	   public Element3(String s){ 
	    this.s =  s; 
	   } 
	   public String toString(){ 
	    return s; 
	   } 
	   public int compareTo(Object o){ 
	    return -1; 
	   } 
	   public boolean equals(Object obj) { 
	    return s.equals(((Element2)obj).s); 
	   }
	}
/**
*运行结果:[ss, qq, ss]  --没有实现元素不重复。
*原因:重写了compareTo方法返回值是-1,把所有的元素都作为不同的元素处理。
*/
public class TestHashSet1 {
	public static void main(String[] args) {
		Set set = new HashSet();
		set.add(new Element4("kkk"));
		set.add(new Element4("jjj"));
		set.add(new Element4("kkk"));
		System.out.println(set);
	}
}
class Element4{
	String s;
	public Element4(String s) {
		super();
		this.s = s;
	}
	@Override
	public boolean equals(Object obj) {
		return s.equals(((Element4)obj).s);
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return s;
	}
}
/**
 * 运行结果:[jjj, kkk, kkk]  --重写了equals没有达到元素不重复的要求
 */
public class TestHashSet2 {
	public static void main(String [] args){
		Set set = new HashSet();
		set.add(new Element5("kkk"));
		set.add(new Element5("jjj"));
		set.add(new Element5("kkk"));
		System.out.println(set);
	}
}
class Element5{
	String s;
	public Element5(String s) {
		super();
		this.s = s;
	}
	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return s.hashCode();
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return s;
	}
	@Override
	public boolean equals(Object obj) {
		return s.equals(((Element5)obj).s);
	}
}
/**
 * 运行结果:[jjj, kkk]--达到了元素不重复的要求
 * 值得注意的是:在类Element5中重写了hashCode方法和equals方法,这两个方法都是不可缺的
 * 缺了其中一个就不能达到元素不重复的效果了。
 * 看看源码的方法:
 *     public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }
    其中的有这样的条件:e.hash == hash && ((k = e.key) == key || key.equals(k))可以看出,如果这个条件成立的话,
    那么就是说明元素的重复的,就不会添加元素了。而这个条件所需要的恰好是hashCode方法和equals方法。所以说HashSet实现
    元素不重复是使用了:hashCode方法和equals方法。
 */

呵呵,分析的比较粗糙,大家参考哈就是了哈。其实有一个CopyOnWriteArraySet,这个类是AbstractSet的子类。它在实现元素不重复的时候就是用的是List遍历的,采用了equals来实现元素不重复,大家有机会可以看看了。
分享到:
评论

相关推荐

    C++set函数学习

    set由于保证元素唯一性,适用于只需要存储不重复单词的场景;而multiset适用于需要统计每个单词出现次数的情况。例题要求输出排序后的单词列表,并且重复的单词只输出一次,set正适合这种情况。 在编程实践中,set...

    map和set的异同

    在`set`容器中,元素不能重复,且元素默认按照升序排列。 #### 三、共同点 1. **底层实现**:在C++ STL中,`map`和`set`都是基于红黑树(Red-Black Tree)实现的。红黑树是一种自平衡二叉查找树,能够保证树的高度...

    集合类型IntSet以及运算

    在实际应用中,`IntSet`常用于各种场景,如数据库索引、算法实现(如图论中的并查集)、统计计算(如不重复计数)等。例如,在网络爬虫中,可以使用`IntSet`来存储已访问过的URL,避免重复抓取;在编译器中,`IntSet...

    java 去除重复元素

    HashSet是一个不允许有重复元素的集合,当我们尝试将一个数组中的所有元素添加到HashSet时,它会自动过滤掉重复元素。例如: ```java Integer[] array = {1, 2, 3, 2, 4, 3, 5}; Set&lt;Integer&gt; set = new HashSet...

    Set实现类1

    Set是Java集合框架的一部分,主要用于存储不重复的元素。它有多种实现类,如HashSet和TreeSet,每个类都有其特定的特性和用途。 1. **HashSet** - **构造函数**:HashSet提供了多种构造方法,包括无参构造、接受...

    CustomSet.zip

    在Java编程语言中,HashSet是一种常用的集合类,它实现了Set接口,不包含重复元素,并且不保证元素的顺序。在给定的“CustomSet.zip”压缩包中,我们看到一个名为“CustomSet.java”的文件,这很可能是用户自定义的...

    python中的set实现不重复的排序原理

    为了确保`School`中的教师实例不重复,开发者最初尝试使用`set`来存储这些实例。然而,由于`set`要求其元素必须是可哈希的,也就是说,这些元素必须拥有`__hash__`方法,而最初的`Teacher`类并没有提供这个方法,...

    python内置的集合set中元素顺序-python基础教程:set(集合).pdf

    Python中的集合(Set)是一种非常实用的数据结构,它在概念上类似于数学中的集合,用于存储不重复的元素。集合的特点是没有特定的顺序,且不允许有重复的元素。在Python中,集合是由哈希表(Hash Table)实现的,这...

    map和set的模拟实现

    Set则是一个不包含重复元素的集合,同样支持快速查找。 为了模拟实现Map和Set,我们需要首先封装红黑树。这通常包括以下几个步骤: 1. 定义节点结构:创建一个结构体或类,表示红黑树的节点,包括键、值、颜色、左...

    List和Set使用retainAll方法的比较

    - **Set**:Set是无序且不包含重复元素的集合。它不支持索引访问,但提供了一种唯一性保证。常见的Set实现类有HashSet和TreeSet。 2. **retainAll方法的实现原理** - 对于`List`,`retainAll`方法的实现通常是...

    java 运用集的相关类(Set)

    1. HashSet:这是最常用的Set实现,它不保证元素的顺序,允许使用null值,但不允许元素重复。HashSet内部使用哈希表来存储元素,因此添加、删除和查找操作的平均时间复杂度为O(1)。 2. TreeSet:TreeSet基于红黑树...

    Java中Set的深入研究

    Set接口是Java集合框架的一部分,它代表了一个数学抽象集合,即不允许包含重复元素的集合。更正式地讲,根据其Javadoc文档,Set是一个不包含任何重复元素的集合。具体来说,Set不允许包含满足`e1.equals(e2)`条件的...

    C++ Set(集合)

    set 是一个内部自动有序且不含重复元素的容器。 set 最主要的作用就是自动去重并按升序排序,适用于需要去重但是又不方便直接开数组的情况。 set 中的元素是唯一的,其内部采用“红黑树”实现。 注:本文章只列举 ...

    C++ 集合 set 例子

    - **唯一性**:`set`不允许重复元素,尝试插入重复元素时,操作会被忽略。 - **非随机访问**:由于其实现方式,`set`不支持随机访问,只能通过迭代器进行顺序访问。 ### `set`的函数列表 #### 基本操作 - **begin...

    Set用法及与List的区别

    Set是一个不允许有重复元素的集合,它遵循唯一性原则。在Set接口下有许多实现类,如HashSet、TreeSet和LinkedHashSet等。我们以`HashSetDemo.java`为例,探讨HashSet的使用方法。 `HashSet`是Java中最常用的Set实现...

    javascript过滤数组重复元素的实现方法.docx

    ### JavaScript 过滤数组重复元素的实现方法 #### 背景介绍 在日常的Web开发工作中,我们经常需要处理各种数据结构,其中数组是最常用的数据类型之一。随着项目的复杂度增加,对于数组中可能出现的重复元素进行有效...

    219. 存在重复元素 II(set+滑窗)1

    5. 如果当前元素不在哈希集合中,将其添加到 `map` 中,表示该元素进入了滑动窗口。 6. 遍历结束后,如果没有找到符合条件的重复元素,则返回 `False`。 这种方法的时间复杂度为 O(n),空间复杂度也为 O(n),其中 n...

    集合的概念及应用和HashSet保证数据不重复的原理

    总结来说,集合是Java编程中不可或缺的一部分,而HashSet通过哈希表提供了一种高效存储和检索不重复元素的方式。理解其工作原理对于优化代码性能和解决实际问题具有重要意义。在日常开发中,我们应该根据具体需求...

    JAVA IntSet 数列集合

    如果该值已经存在,此操作通常不执行任何操作,因为集合不允许重复元素。 3. **移除数字**: 使用`remove(int value)`方法可以移除集合中的特定整数值。如果该值不存在于集合中,此操作也不会抛出异常。 4. **...

    set映射(视频)

    在IT领域,集合是数据结构中的重要组成部分,用于存储不重复的数据。在Java编程语言中,`Set`接口是集合框架的一部分,它继承自`Collection`接口,提供了不允许重复元素的存储功能。在这个主题中,我们将深入探讨`...

Global site tag (gtag.js) - Google Analytics