`
kaidi0314
  • 浏览: 83230 次
  • 性别: 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;    //这里只是测试方便这么写了,事实上,如果这么写,是没有任何存储效率的。
   }
}

 

分享到:
评论

相关推荐

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

    set集合判断集合中是否有⽆元素_Python⼊门教程笔记(五) 集合(set)及函数 三九、什么是 三九、什么是set 在前⾯,我们学习了dict,知道dict的key是不重复的,当我们往dict⾥添加⼀个相同key的value时,新的value...

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

    #set会生成一个元素无序且不重复的可迭代对象,也就是我们常说的去重 if len(set_lst)==len(lst): print('列表里的元素互不重复!') else: print('列表里有重复的元素!') 二、用append的方式把原列表中的元素添加...

    java集合知识-map、set等

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

    利用Set集合去除List集合中重复元素、字符串中的重复子串

    一:Set集合去掉List集合中重复元素 public static void main(String[] args) { //利用set集合 去除ArrayList集合中的重复元素 ArrayList list = new ArrayList(); list.add("1"); list.add("1"); list.add("2...

    java 中HashMap、HashSet、TreeMap、TreeSet判断元素相同的几种方法比较

    主要介绍了从源码的角度浅析HashMap、TreeMap元素的存储和获取元素的逻辑;从Map与Set之间的关系浅析常用的Set中元素的存储和判断是否重复的逻辑,需要的朋友可以参考下

    Python实现判断给定列表是否有重复元素的方法

    本文实例讲述了Python实现判断给定列表是否有重复元素的方法。分享给大家供大家参考,具体如下: 题目很简单,只是简单温习一个方法,most_common,这是collection模块中Counter类的方法,具体方法用法可以去查 下面...

    C++ Set(集合)

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

    java中set、list和map的使用方法实例

    // set容器中的对象不允许重复 // set容器接口的实现类有HashSet和 LinkedHashSet两个 // HashSet不保证迭代顺序, LinkedHashSet按照元素插入的顺序迭代. // 学习List对象容器的使用 // List容器中的对象允许重复 ...

    Java集合框架Set接口.pdf

    Java集合框架中的Set接口是一种不允许包含重复元素的集合。Set接口继承自Collection接口,因此它具有Collection接口定义的所有方法。同时,Set接口还具有自己的特殊方法,例如:添加元素、删除元素、判断元素是否...

    Python语言基础:set集合运用.pptx

    set集合是一个元素无序不重复的序列,可以使用大括号{}或set()函数创建集合。 语法格式: parame={value01,value02,………} 或 set(value) 实例:创建set集合。 #第一种创建set集合 basket={"apple","orange","pear...

    set.list.map接口

    1. Set(集合)里面的元素是无序的,但没有重复的元素 2. 两个实现类HashSet(LinkHashSet)和TreeSet,TreeSet有排序功能(Set set=new TreeSet();set.add(new Integer(8)); set.add(new Integer(4)); set.add(new ...

    List、Set、Map的特点及遍历方法

    set元素放入无顺序 ,不可重复元素 set与list的对比 set检查元素效率低下,删除和插入的效率高,不会引起元素位置改变 list和数组相似,list可实现动态增长,查找元素效率高,插入和检查的效率低,会

    集合概述set、List、Map

     Set – 对象之间没有指定的顺序,不允许重复元素  List– 对象之间有指定的顺序,允许重复元素,并引入位置下标。  Map – 接口用于保存关键字(Key)和数值(Value)的集合,集合中的每个对象加入时都提供...

    测量程序编制 - python 52数据类型:Set(集合)-函数.pptx

    Set(集合)——函数 Set(集合)——函数 序号 方法 描述 1 add() 为集合添加元素 2 clear() 移除集合中的所有元素 ...返回两个集合中不重复的元素集合。 15 symmetric_difference_update() 移除当前

    set容器无重复注意问题.png

    凡是以hashcode为存储位置计算的容器都需要重写hashcoe方法,为什么重写类的hashcode和equals方法?如果不重写会有后果?以及set容器的元素储存方式

    测量程序编制 - python 51数据类型:Set(集合)-对称差集.pptx

    2) symmetric_difference()方法:返回两个集合中不重复的元素集合,即会移除两个集合中都存在的元素 语法: set. symmetric_difference(set1, set2 ... etc) set1 -- 必需,要查找相同元素的集合,可以是任何序列 ...

    测量程序编制 - python 49数据类型:Set(集合)-并集.pptx

    即包含了所有集合的元素,重复的元素只会出现一次语法: set.union(set1, set2...)set1 -- 必需,要查找相同元素的集合set2 -- 可选,可以是任何序列,可以多个,多个使用逗号 , 隔开 若是字典,按键比较返回值:...

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

    否则,返示例 1:示例 2:示例 3:def containsNearbyDuplicate(self, nums: List[int], k: int) -&gt;

    JAVA集合(List,Set,Map)

     · Set 接口继承 Collection,但不允许重复,使用自己内部的一个排列机制。 · List 接口继承 Collection,允许重复,以元素安插的次序来放置元素,不会重新排列。 · Map接口是一组成对的键-值对象,即所持有...

    day016-list和set笔记以及代码.zip

    如果是不能存放重复的元素,用Set接口下的实现类 HashSet:如果没有任何排序要求,用HashSet,因为效率高 TreeSet: 如果有排序要求用TreeSet, 如果是自然排序,需要元素实现Comparable接口,重写compareTo方法 ...

Global site tag (gtag.js) - Google Analytics