Java集合系列(三)

来源:互联网 发布:淘宝会员名大全 好听 编辑:程序博客网 时间:2024/06/05 05:52

前言


上一节介绍了Collecton接口,List接口,以及其子类ArrayList与vector的相关概念及其基本应用,本节将继续学习Collection接口的另一个子接口及其子类的基本概念以及应用

Set接口

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

public interface Set<E> extends Collection<E>

从定义上可以发现,Set接口与List接口的定义并没有太大的区别。但是Set接口的主要方法与Collection是一致的,也就是说Set接口并没有对Collection接口进行扩充,只是比Collection接口的要求更加严格了,不能增加重复元素。

Set接口的实例无法像List接口那样可以进行双向输出,因为此接口没有提供像List接口定义的get(int index)方法。

Set接口的常用子类

1. 散列的存放: HashSet

HashSet是Set接口的一个子类,主要的特点是,里面不能存放重复元素,而且采用散列的存储方式,所以没有顺序。

范例

package ljz;import java.util.HashSet;import java.util.Set;public class HashSetDemo01 {    public static void main(String[] args){    Set<String> allSet=new HashSet<String>();    allSet.add("A");    allSet.add("B");    allSet.add("C");    allSet.add("D");    allSet.add("E");    System.out.print(allSet);    }}

程序运行结果:

[D,A,C,B,E]

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

2.有序的存放:TreeSet

如果想对输入的数据进行有序的排列,则要使用TreeSet子类。TreeSet类的定义如下:

public class TreeSet<E> extends AbstractSet<E>implements SortedSet<E>,Cloneable,SeriaLizable 

而AbstractSet也是继承AbstractCollection,此类的定义如下:

public abstract class AbstractSet<E> extendsAbstractCollection<E> implements Set<E>

范例

  • 验证TreeSet类
package ljz;import java.util.Set;import java.util.TreeSet;public class TreeSetDemo01 {    public static void main(String[] args){    Set<String> allSet=new TreeSet<String>();    allSet.add("C");    allSet.add("C");    allSet.add("C");    allSet.add("D");    allSet.add("B");    allSet.add("A");    allSet.add("E");    System.out.println(allSet);    }}

程序运行结果:

[A, B, C, D, E]

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

指定排序规则

import java.util.Set ;import java.util.TreeSet ;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 per){        if(this.age>per.age){            return 1 ;        }else if(this.age<per.age){            return -1 ;        }else{            return 0 ;        }    }};public class TreeSetDemo03{    public static void main(String args[]){        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) ;    }};

程序运行结果:

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

提问:如何判断对象是否重复?

想判断对象是否重复,则必须覆写Object类中的equals()方法,才能完成对象是否相等的判断,但是只覆写equals()方法是不够的,还需要覆写hashCode()方法,此方法表示一个哈希编码,可以简单地理解为表示一个对象的编码。一般的哈希码是通过公式计算的,可以将类中的全部属性进行适当的计算,以求出一个不会重复的哈希码

关于hashCode的理解

关于hashCode也可以从实际生活中理解,例如:每个人都会有一个唯一的身份证号,当进行入口省察的时候,首先肯定会检查身份证是否一致(相当于使用hashCode),如果一致的话,则在将每个人的信息进行匹配(相当于对象比较使用equals()),如果全部符合,则表示通过审查。

范例:

import java.util.HashSet;import java.util.Set;class Person{private String name;Private int age;public Person(String name,int age){this.name=name;this.age=age;}public boolean equals(Object obj){if(this==obj){return true;}if(!(obj instanceof Person)){return false;}Person p=(Person) obj; if(this.name.equals(p.name)&&this.age==p.age){return true;}else{return false;}}public int hashCode(){return this.name.hashCode()*this.age;}}public class RepeatDemo02{public static void main(String[] args){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) ;    }};

程序运行结果:

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

从最后输出的结果中可以发现,集合中的重复内容消失了,就是因为equals和hashCode共同作用的结果

SortedSet接口

从TreeSet类的定义中可以发现,TreeSet中实现了SortedSet接口,此接口主要用于排序操作,即实现此接口的子类都属于排序的子类。SortedSet接口的定义如下:

public interface SortedSet<E> extends Set<E>

发现此接口也继承了Set接口。
这里写图片描述

范例

import java.util.Set;import java.util.SortedSet;public class TreeSetDemo05{public static void main(String[] args){SortedSet<String> allSet=new TreeSet<String>(){allSet.add("A");allSet.add("B");allSet.add("C");allSet.add("D");allSet.add("E");System.out.println("第一个元素:"+allSet.first());System.out.println("最后一个元素:"+allSet.last());System.out.println("headSet元素:"+allSet.headSet("C"));System.out.println("tailSet元素:"+allSet.tailSet("C"));System.out.println("subSet元素:"+allSet.subSet("B","D"));}}

程序运行结果:

第一个元素:A
最后一个元素:E
headSet元素:[A, B]
tailSet元素:[C, D, E]
subSet元素:[B, C]

未完待续!

原创粉丝点击