黑马程序员——集合(二)Set

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
在上一篇的集合(一)中,介绍了Collection的框架,以及List。这篇文章将继续介绍集合的另外两个容器,Map和Set。

Set:存储的元素是无序的,不可重复的!
1.无序性:无序性!= 随机性。真正的无序性,指的是元素在底层存储的位置是无序的。
2.不可重复性:当向Set中添加进相同的元素的时候,后面的这个不能添加进去。

说明:要求添加进Set中的元素所在的类,一定要重写equals()和hashCode()方法。 进而保证Set中元素的不可重复性!
Set中的元素时如何存储的呢?使用了哈希算法。
当向Set中添加对象时,首先调用此对象所在类的hashCode()方法,计算此对象的哈希值,此哈希值
决定了此对象在Set中的存储位置。若此位置之前没有对象存储,则这个对象直接存储到此位置。若此位置
已有对象存储,再通过equals()比较这两个对象是否相同。如果相同,后一个对象就不能再添加进来。 万一返回false呢,都存储。(不建议如此)

要求:hashCode()方法要与equals()方法一致。
用set集合存入costumer

public class Customer {
    private String name;
    private Integer id;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Customer(String name, Integer id) {
        super();
        this.name = name;
        this.id = id;
    }
    public Customer() {
        super();
    }
    @Override
    public String toString() {
        return "Customer [name=" + name + ", id=" + id + "]";
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Customer other = (Customer) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}

public void testTreeSet3() {

        TreeSet set = new TreeSet(new Comparator() {
            public int compare(Object o1, Object o2) {
                if (o1 instanceof Customer && o2 instanceof Customer) {
                    Customer c1 = (Customer) o1;
                    Customer c2 = (Customer) o2;
                    int i = c1.getId().compareTo(c2.getId());
                    if (i == 0) {
                        return c1.getName().compareTo(c2.getName());
                    }
                    return i;
                }
                return 0;
            }
        });
        set.add(new Customer("AA", 1003));
        set.add(new Customer("BB", 1002));
        set.add(new Customer("GG", 1004));
        set.add(new Customer("CC", 1001));
        set.add(new Customer("DD", 1001));

        for (Object str : set) {
            System.out.println(str);
        }
    }

Set接口中的方法和Collection一致。
|–HashSet:内部数据结构是哈希表,是不同步的。
|–TreeSet:可以对Set集合中的元素进行排序,是不同步的

HashSet保证元素唯一性的方法:
是通过元素的两个方法,hashCode();和equals();方法来完成,如果元素的hasCode值相同,才会判断equals方法来完成,如果元素的hascode值不同,不会调用equals
示例,用hashset ,实现存储person对象,并且无重复。
代码:

public class Person {
    private String name;
    private int age;

    Person(String name, int age){
        this.name=name;
        this.age=age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public boolean equals(Object obj) {//判断两队想是否相等
        if (!(obj instanceof Person))//判断传入的对象是不是Person类
            return false;

            Person p= (Person) obj;
        System.out.println(this.name+":equals:"+p.name);
        return this.name.equals(p.name)&&this.age==p.age;
    }

    public int hashCode(){//复写了hashcode();
        System.out.println(this.getName()+this.name.hashCode()+this.age*21);
        return this.name.hashCode()+this.age*21;
    }
}

public class HashSetDemo {
    public static void main(String[] args){
        HashSet hs=new HashSet();
        hs.add(new Person("le1",11));
        hs.add(new Person("le2",11));
        hs.add(new Person("le1",11));
        hs.add(new Person("le3",11));

        printHS(hs);


    }
    public static void printHS(HashSet hs){
        for (Iterator it=hs.iterator();it.hasNext();){
            Person p= (Person) it.next();
            System.out.println(p.getName()+"--"+p.getAge());
        }
    }
}

TreeSet
Tree的底层数据结构是二叉树,所以TreeSet 可以确保集合元素处于排序状态。TreeSet: 1.向TreeSet中添加的元素必须是同一个类的。
2.可以按照添加进集合中的元素的指定的顺序遍历。像String,包装类等默认按照从小到大的顺序遍历。
3.当向TreeSet中添加自定义类的对象时,有两种排序方法:①自然排序②定制排序
4.自然排序:要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)的抽象方法
在此方法中,指明按照自定义类的哪个属性进行排序。

5.向TreeSet中添加元素时,首先按照compareTo()进行比较,一旦返回0,虽然仅是两个对象的此
属性值相同,但是程序会认为这两个对象是相同的,进而后一个对象就不能添加进来。

compareTo()与hashCode()以及equals()三者保持一致!

同TreeSet存储学生对象,根据学生对象的年龄姓名排序
代码:

public class Student implements Comparable{
    private String name;
    private int age;
    Student(String name,int age){
        this.name=name;
        this.age=age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public int compareTo(Object obj) {//复写了比较方法
            if (!(obj instanceof Student)){
                throw new RuntimeException("传入对象有误");}
            Student s= (Student) obj;

            if (this.age>s.age)//根据年龄排序
                return 1;
            else if (this.age==s.age)//年龄相同根据姓名排序
                return this.name.compareTo(s.name);
           else
                return -1;

    }
}
public class TreeSetDemo {
    public static void main(String[] args){
        TreeSet ts=new TreeSet(new MyCompare());
        ts.add(new Student("le1",12));
        ts.add(new Student("le2",20));
        ts.add(new Student("le3",32));
        ts.add(new Student("le1",13));
        ts.add(new Student("le2",12));

        printTS(ts);

    }
    public static void printTS(TreeSet ts){
        for (Iterator it=ts.iterator();it.hasNext();){
            Student s=(Student) it.next();
            System.out.println(s.getName()+"--"+s.getAge());
        }
    }
}

再上一个离子的基础上,构造一个比较器可以改变排序方式

public class MyCompare implements Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        Student s1=(Student)o1;
        Student s2=(Student)o2;
//线比较姓名,在比较年龄。
        int num=s1.getName().compareTo(s2.getName());
        if (num==0)
            return new Integer( s1.getAge()).compareTo(new Integer(s2.getAge()));
        return num;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值