`

集合类 Set

    博客分类:
  • Java
 
阅读更多

http://www.cnblogs.com/yuchao/archive/2011/02/26/1965714.html

 

Set接口的定义

Set接口也是Collection接口的子接口,但是与Collection或List接口不同的是,Set接口中不能加入重复的元素,其定义如下:

public interface Set<E> extends Colletion<E>

从定义上可以发现,Set接口与List接口的定义并没有太大的区别,但是Set接口的主要方法与Collection是一致的,也就是说Set接口并没有对Collection进行扩充。

Set接口的常用子类

1.散列的存放:HashSet

 

复制代码
 1 package com.yuchao.collection;
 2 
 3  import java.util.HashSet;
 4  import java.util.Set;
 5 
 6 public class HashSetDemo {
 7 
 8     /** 9      * @param args
10 */
11     public static void main(String[] args) {
12         // TODO Auto-generated method stub13         Set<String> allSet=new HashSet<String>();
14         allSet.add("A");
15         allSet.add("B");
16         allSet.add("C");
17         allSet.add("C");
18         allSet.add("D");
19         allSet.add("D");
20         allSet.add("D");
21         allSet.add("E");
22         System.out.println(allSet);    
23     }
24 
25 }
复制代码

 

程序运行结果:

[D,A,C,B,E]

从程序的运行结果可以清楚地看出,对于重复元素只会增加一次,而且程序运行时向集合中加入元素的顺序并不是集合中的保存顺序,证明HashSet类中的元素是无序排列的。

2.有序的存放:TreeSet

 

复制代码
 1 package com.yuchao.collection;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 public class HashSetDemo {
 7 
 8     /** 9      * @param args
10 */
11     public static void main(String[] args) {
12         // TODO Auto-generated method stub13         Set<String> allSet=new HashSet<String>();
14         allSet.add("A");
15         allSet.add("B");
16         allSet.add("C");
17         allSet.add("C");
18         allSet.add("D");
19         allSet.add("D");
20         allSet.add("D");
21         allSet.add("E");
22         System.out.println(allSet);    
23     }
24 
25 }
复制代码

 

程序运行结果:

[A,B,C,D,E]

程序在向集合中插入数据时是没有顺序的,但是输出之类数据是有序的,所以TreeSet是可以排序的。

3.关于TreeSet的一些思考

既然TreeSet本身是可以排序的,那么自定义的一个类,是否也可以随意进行排序呢?

 

复制代码
 1 package com.yuchao.collection;
 2 
 3 import java.util.Set;
 4 import java.util.TreeSet;
 5 
 6 public class TreeSetDemo {
 7 
 8     /** 9      * @param args
10 */
11     public static void main(String[] args) {
12         // TODO Auto-generated method stub13         Set<Person> allSet=new TreeSet<Person>();
14         allSet.add(new Person("张三", 30));
15         allSet.add(new Person("李四", 31));
16         allSet.add(new Person("王五", 32));
17         allSet.add(new Person("王五", 32));
18         allSet.add(new Person("王五", 32));
19         allSet.add(new Person("赵六", 33));
20         allSet.add(new Person("孙七", 33));
21         System.out.println(allSet);        
22 
23     }
24 
25 }
26 
27 class Person
28 {
29     private String name;
30     private int age;
31     public Person(String name,int age)
32     {
33         this.name=name;
34         this.age=age;
35     }
36     
37     public String toString()
38     {
39         return "姓名:"+this.name+";"+"年龄:"+this.age;
40     }
41 }
复制代码

 

程序运行时出现以下错误:

Exception in thread "main" java.lang.ClassCastException: com.yuchao.collection.Person 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.yuchao.collection.TreeSetDemo.main(TreeSetDemo.java:15)

以下程序代码出现了类转换异常,会出现这样的问题,是因为TreeSet中的元素是有序存放,所以对一个对象必须指定好其排序规则,且TreeSet中每个对象所在的类都必须实现Comparable接口才可以正常使用。

 

复制代码
 1 package com.yuchao.collection;
 2 
 3 import java.util.Set;
 4 import java.util.TreeSet;
 5 
 6 public class TreeSetDemo {
 7 
 8     /** 9      * @param args
10 */
11     public static void main(String[] args) {
12         // TODO Auto-generated method stub13         Set<Person> allSet=new TreeSet<Person>();
14         allSet.add(new Person("张三", 30));
15         allSet.add(new Person("李四", 31));
16         allSet.add(new Person("王五", 32));
17         allSet.add(new Person("王五", 32));
18         allSet.add(new Person("王五", 32));
19         allSet.add(new Person("赵六", 33));
20         allSet.add(new Person("孙七", 33));
21         System.out.println(allSet);
22     }
23 
24 }
25 
26 class Person implements Comparable<Person>
27 {
28     private String name;
29     private int age;
30     public Person(String name,int age)
31     {
32         this.name=name;
33         this.age=age;
34     }
35     
36     public String toString()
37     {
38         return "姓名:"+this.name+";"+"年龄:"+this.age;
39     }
40     
41     public int compareTo(Person person)
42     {
43         if(this.age>person.age)
44         {
45             return 1;
46         }else if(this.age<person.age){
47             return -1;
48         }else{
49             return 0;
50         }
51     }
52 }
复制代码

 

程序运行结果:

[姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32, 姓名:赵六;年龄:33]

从程序的运行结果中可以发现,重复的”王五“对象只有一个;”赵六“和”孙七“年龄重复,但是”孙七“并没有加入到集合中。这是由于采用了比较器造成的,因为比较器操作时如果某个属性没有进行比较的指定,则也会认为是同一个对象,所以此时应该在Person类的compareTo方法中增加按姓名比较。

 

修改Person比较器
package com.yuchao.collection;

import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub        Set<Person> allSet=new TreeSet<Person>();
        allSet.add(new Person("张三", 30));
        allSet.add(new Person("李四", 31));
        allSet.add(new Person("王五", 32));
        allSet.add(new Person("王五", 32));
        allSet.add(new Person("王五", 32));
        allSet.add(new Person("赵六", 33));
        allSet.add(new Person("孙七", 33));
        System.out.println(allSet);
    }

}

class Person implements Comparable<Person>
{
    private String name;
    private int age;
    public Person(String name,int age)
    {
        this.name=name;
        this.age=age;
    }
    
    public String toString()
    {
        return "姓名:"+this.name+";"+"年龄:"+this.age;
    }
    
    public int compareTo(Person person)
    {
        if(this.age>person.age)
        {
            return 1;
        }else if(this.age<person.age){
            return -1;
        }else{
            return this.name.compareTo(person.name);
        }
    }
}

 

程序输出结果:

[姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32, 姓名:孙七;年龄:33, 姓名:赵六;年龄:33]

以下程序运行结果出现了”孙七",而且去掉了重复的内容,但此时的重复内容去掉,并不是真正意义上的去掉重复元素。因为此时靠的是Comparable接口完成的,而如果换成HashSet则也会出现重复的内容,所以要想真正的去掉重复元素,则必须深入研究Object类。

提示:想要判断对象是否重复必须覆盖Object类中的equals()方法,但同时必须覆盖hashCode()方法,此方法表示一个哈希编码,一般哈希码是通过公式进行计算的,可以将类的全部属性进行适当计算,以求出一个不会重复的哈希码。

 

修改equals()、hashCode()去除重复元素
package com.yuchao.collection;

import java.util.HashSet;
import java.util.Set;

public class TreeSetDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //Set<Person> allSet=new TreeSet<Person>();        Set<Person> allSet=new HashSet<Person>();
        allSet.add(new Person("张三", 30));
        allSet.add(new Person("李四", 31));
        allSet.add(new Person("王五", 32));
        allSet.add(new Person("王五", 32));
        allSet.add(new Person("王五", 32));
        allSet.add(new Person("赵六", 33));
        allSet.add(new Person("孙七", 33));
        System.out.println(allSet);
    }

}

class Person 
{
    private String name;
    private int age;
    public Person(String name,int age)
    {
        this.name=name;
        this.age=age;
    }
    
    public String toString()
    {
        return "姓名:"+this.name+";"+"年龄:"+this.age;
    }
    
    public boolean equals(Object object)
    {
        if(this==object)
        {
            return true;
        }
        if(!(object instanceof Person))
        {
            return false;
        }
        Person person=(Person)object;
        if(this.name.equals(person.name)&&this.age==person.age)
        {
            return true;
        }
        else 
        {
            return false;
        }
    }
    
    public int hashCode()
    {
        return this.name.hashCode()*this.age;
    }
    
}

提示:在实际开发中经常会碰到区别同一对象的问题,所以,一个完整的类最好覆写Object类的hashCode()、equals()、toString()3个方法。

分享到:
评论

相关推荐

    java集合类详解(set list ArrayList等java集合类详述)

    集合类可以分为三大类:Collection、List 和 Set。 Collection 是集合框架中的根接口,提供了基本的集合操作,如 add、remove、contains 等。Collection 接口没有实现类,因此需要通过其子接口来实现。 Set 是一个...

    义一个整数集合类integerSet。这种类型的对象可以存储10个20~80之间的整数,即他的内部有一个整型数组存储数据。编程:

    根据给定文件的信息,我们可以对整数集合类`integerSet`进行详细的知识点解析与功能实现探讨。 ### 整数集合类integerSet #### 类定义 `integerSet`类用于存储10个位于20至80之间的整数。此类包含了一个整型数组...

    Java集合类List-Set-Map的区别和联系.doc

    Java 集合类 List-Set-Map 的区别和联系 Java 集合类 List、Set 和 Map 是 Java 语言中最基本的集合类,它们之间存在着紧密的联系和区别。在本文中,我们将对 Java 集合类 List、Set 和 Map 的区别和联系进行详细的...

    集合类型IntSet以及运算

    在本场景中,我们关注的是一个特定的集合类型——`IntSet`,它专门用于存储整型数值。`IntSet`通常以高效、无序且不允许重复的方式来组织数据。在本文中,我们将深入探讨`IntSet`的定义、实现和测试,以及如何在实际...

    C++集合模板类与常见集合算法的实现

    这份代码用 C++ 的模板类实现了一个集合类 Set,其 API 参考借鉴了 STL 中的 vector 类,采用动态内存及链表进行元素管理,并实现了一些常见的集合算法:并集、交集,也实现了随机下标的存取。

    205-习题作业-作业十四1

    在上面的代码中,我们定义了一个集合类 Set,使用模板参数 T 来表示集合元素的类型。集合类中有三个友元函数,分别对应于并、交、差运算。私有成员变量 elem 用于存储集合元素,size 和 volume 分别表示当前集合元素...

    创建一个IntegerSet(集合类).zip

    本文将深入探讨如何在C++中创建一个名为`IntegerSet`的集合类,以及在这个过程中涉及的关键知识点。 首先,集合类通常用于存储和操作一组特定类型的元素,比如整数。在C++中,我们可以通过定义一个类来实现这个概念...

    java自定义集合类

    自定义集合类则是开发者根据特定需求扩展Java集合框架的行为,以满足个性化或特定业务场景的功能需求。以下是对"java自定义集合类"这一主题的详细解释。 首先,Java集合框架包括接口(如List、Set、Map)和实现这些...

    java集合类list-set-map.doc

    java集合类list-set-map.doc

    用C++实现集合(Set)对象功能

    首先,我们需要定义一个集合类,通常以`Set`为名称。这个类应该包含一个内部数据结构来存储元素,如动态数组或关联数组(如红黑树)。这里我们使用STL中的`std::set`作为底层数据结构,因为它自动处理元素的唯一性和...

    CSet源代码,集合类的C++源代码

    在C++编程语言中,集合类(通常称为Set)是一种数据结构,用于存储不重复的元素。`CSet`可能是作者自定义的一个集合类实现,它可能提供了类似于STL(Standard Template Library)中的`std::set`容器的功能。STL是C++...

    Set集合BUG

    修改头文件sysset.h ,使C++builder中Set集合类ToInt出错的问题解决

    整数集合类的各种操作

    在编程领域,集合类是数据结构中的重要组成部分,主要用于存储一组不重复的元素。在Java中,`java.util.Set`接口及其子接口如`HashSet`、`TreeSet`等提供了整数集合的操作。本篇文章将深入探讨如何实现整数集合的...

    java集合类的代码

    Java集合类是Java编程语言中一个非常重要的概念,它提供了数据结构和算法的实现,使得在处理一组对象时更加高效和灵活。Java集合框架包括接口(如List、Set、Queue等)和实现这些接口的类(如ArrayList、HashSet、...

    java集合类演示源码

    集合类的框架为集合的实现者提供了大量的接口和抽象类,并对其中的某些机制给予了描述,例如,Iterator(迭代协议)。实现Comparable接口或Comparator接口,用户可以根据需要对集合中的元素进行排序。为了方便用户...

    VC++集合类,详细例子。

    MFC 集合类可以按形态和设计方案来分类。MFC 为三种类型的集合形态提供了类: 列表 数组 映射 MFC 还提供三种类型的设计方案: 不使用 C++ 模板。 使用由简单元素组成的基于 C++ 模板的集合。 使用由类型...

    java常用集合类总结

    "Java集合类总结" Java集合类是Java语言中的一种重要数据结构,用于存储和管理数据。Java集合类可以分为两种:Collection接口和Map接口。Collection接口有两个子接口:List接口和Set接口。List接口是有序的,可以...

    java集合类详解

    Java集合类是Java语言中用来存储数据的结构,它们是Java开发中非常重要的组件。在Java 2平台之前,集合框架的组成较为零散,自Java 2平台的JDK 1.2版本之后,引入了集合框架(Collections Framework),为集合类提供...

    Java集合类详解总结

    ### Java集合类详解总结 在Java编程中,集合框架(Collection Framework)是处理一组对象的强大工具,它提供了标准的数据结构来存储和操作这些对象。Java集合框架主要包括`Collection`、`Set`、`List`、`Queue`、`...

Global site tag (gtag.js) - Google Analytics