`
kaidi0314
  • 浏览: 86171 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Set的元素重复是如何判断的

阅读更多

相关链接: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;    //这里只是测试方便这么写了,事实上,如果这么写,是没有任何存储效率的。
   }
}

 

分享到:
评论

相关推荐

    基于Python的重复元素判断.docx

    在第一种方法中,我们首先将列表转换为集合,通过比较集合的长度和原列表的长度来判断是否有重复元素。如果两者长度相等,那么列表中的元素就是唯一的;反之,如果长度不相等,就说明存在重复元素。例如: ```...

    java集合知识-map、set等

    Set:元素不可以重复,是无序。p508 Set接口中的方法和Collection一致。 |--HashSet: 内部数据结构是哈希表 ,是不同步的。 如何保证该集合的元素唯一性呢? 是通过对象的hashCode和equals方法来完成对象唯一性的...

    java 去除重复元素

    在Java编程中,处理数据集合时,我们常常会遇到去除重复元素的需求。这可能是为了保持数据的唯一性,或者为了优化存储和计算效率。本文将详细介绍如何在Java中去除重复元素,主要关注数组和列表这两种常见数据结构。...

    set集合判断集合中是否有无元素-Python入门教程笔记(五)集合(set)及函数.pdf

    在Python编程语言中,集合(Set)是一种特殊的数据结构,它包含了唯一且无序的元素。集合的概念类似于数学中的集合论,主要用于存储不重复的数据。集合的创建通常使用`set()`函数,传入一个列表(List)或其他可迭代...

    删除定制整型数组中重复元素输出剩余元素

    在Java编程中,处理整型数组并删除其中的重复元素是一项常见的任务。这通常涉及到集合类的使用,比如HashSet或ArrayList,以及基本的数组操作。本文将深入探讨如何实现这个功能,同时提供一种可能的解决方案。 首先...

    C++set函数学习

    首先,set的特点是保持元素的唯一性,这意味着在set中不会有重复的元素。当你向set中插入一个元素时,如果该元素已存在,则插入操作会忽略该元素,从而保证了set中元素的唯一性。set自动将元素进行排序,默认是升序...

    map和set的异同

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

    java 求两个数组中重复元素源代码

    - 检查数据结构中元素的数量,判断是否为重复元素。 - 可能还会包含一些错误处理和输出结果的代码。 4. **优化**: - **空间优化**:如果只需要知道是否有重复元素,而不是找出所有重复元素,可以使用boolean...

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

    存在重复元素 II" 是 LeetCode 中的一道问题,主要涉及到了数组处理和滑动窗口的概念。这个问题的目标是检查给定的整数数组 `nums` 中是否存在两个不同的索引 `i` 和 `j`,使得它们的值相等 `nums[i] == nums[j]`,...

    在list集合中输入元素,去除重复的元素并输出

    在这个例子中,我们使用`indexOf`和`lastIndexOf`来判断元素是否重复。需要注意的是,这里使用`iterator.remove()`而不是`list.remove()`来删除元素,这可以避免并发修改异常。 ### 三、使用HashSet特性去除重复...

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

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

    set的用法的源代码资源

    - **判断元素存在性**:`in`和`not in`关键字可用于检查元素是否在集合中,如`if 2 in my_set:`。 - **集合的长度**:`len()`函数可以获取集合中元素的数量,如`length = len(my_set)`。 6. **集合的实际应用** ...

    java 运用集的相关类(Set)

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

    List和Set使用retainAll方法的比较

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

    Set用法及与List的区别

    1. **数据存储**:List允许元素重复,而Set不允许。List中的元素有顺序,可以通过索引访问,而Set中的元素没有固定的顺序。 2. **插入与查找效率**:由于Set基于哈希表,通常查找和插入操作比List快。List的插入和...

    List Set Map以及子类的比较 .docx

    Set 集合是一种无序集合,不能存储重复元素。HashSet、LinkedHashSet 和 TreeSet 是 Set 集合的三个常用的实现类。HashSet 使用 Hash 表结构,查询速度快,但不保证元素的顺序。LinkedHashSet 继承了 HashSet,添加...

    集合类型IntSet以及运算

    在编程领域,集合类型是一种非常基础且重要的数据结构,它用于存储一组不重复的元素。在本场景中,我们关注的是一个特定的集合类型——`IntSet`,它专门用于存储整型数值。`IntSet`通常以高效、无序且不允许重复的...

    集合概述set、List、Map

    ### 集合概述:set、List、Map #### 一、集合框架概述 ##### 1.1.1 容器简介 ...- **元素重复性**:是否允许重复元素? 通过对比不同集合类的特点和使用场景,可以帮助开发者更好地选择最适合项目需求的集合类型。

    CustomSet.zip

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

Global site tag (gtag.js) - Google Analytics