码迷,mamicode.com
首页 > 其他好文 > 详细

33.Set

时间:2018-01-23 13:15:47      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:void   集合   同步   哈希   rgs   iter   完成   return   asn   

--Set:元素是无序(存入和取出的顺序不一定一致)的,元素不可以重复
  --HashSet:底层数据结构是哈希表
  --TreeSet:底层数据结构是二叉树。
Set集合的功能和Collection是一致的。  

public class HashSet_08 {

    public static void main(String[] args) {
        
        Demo h1=new Demo();
        Demo h2=new Demo();
        
        sop(h1);//调用的hashCode()方法
        sop(h2);
        
        HashSet hs=new HashSet();
        
        hs.add("java01");
        hs.add("java02");
        hs.add("java03");
        hs.add("java04");
        hs.add("java02");//无允许重复,这个添加失败
        
        sop(hs.add("java05")); //true,添加成功
        sop(hs.add("java05")); //false,添加失败
        
        Iterator it=hs.iterator();
        
        while(it.hasNext()){
            sop(it.next());
        }
    }

    public static void sop(Object obj){
        System.out.println(obj);
    }
}
class Demo{
    public int hashCode(){
        return 199;
    }
}

 

往hashSet集合中存入自定义对象,姓名年龄相同者为同一个人,重复元素

--HashSet:底层数据结构是哈希表
HashSet是如何保证元素唯一性呢?
是通过元素的两个方法,hashCode()和equals()来完成的。
如果元素的HashCode值相同,才会判断equals是否为true。
如果元素的HashCode值不同,不会调用equals。

a1hashCode~~~~~~~~~~~
a2hashCode~~~~~~~~~~~
a3hashCode~~~~~~~~~~~
a2hashCode~~~~~~~~~~~
a2--equals--a2
a1...25
a2...26
a3...27
注意:对于判断元素是否存在以及删除等操作,依赖的方法是元素的hashCode()和equals()方法

public class HashSet_09 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        HashSet hs=new HashSet();
        
        hs.add(new Teacher("a1",25));
        hs.add(new Teacher("a2",26));
        hs.add(new Teacher("a3",27));
        hs.add(new Teacher("a2",26));
        
/*        sop(hs.contains(new Teacher("a1",25))); //true 先判断hashCode
        
        sop(hs.remove(new Teacher("a3",27))); //true 
*/        
        Iterator it=hs.iterator();
        
        while(it.hasNext()){
            Teacher t=(Teacher) it.next();
            sop(t.getName()+"..."+t.getAge());
        }
    }
    
    public static void sop(Object obj){
        System.out.println(obj);
    }

}
class Teacher{
    private String name;
    private int age;
    
    Teacher(String name,int age){
        this.name=name;
        this.age=age;
    }
    
    public String getName(){
        return name;
    }
    
    public int getAge(){
        return age;
    }
    
    public int hashCode(){
        System.out.println(this.name+"hashCode~~~~~~~~~~~");
        return this.name.hashCode()+this.age*39; //*39 保证哈希值唯一性
    }
    
    public boolean equals(Object obj){
        if(!(obj instanceof Teacher)){
            return false;
        }
        
        Teacher t=(Teacher) obj;
        System.out.println(this.name+"--equals--"+t.name);
        
        return this.getName().equals(t.getName()) && this.getAge()==t.getAge();
    }
}

 

Set:无序,不可以重复元素。
  --HashSet:数据结构是哈希表。线程是非同步的。
    保证元素唯一性的原理:判断元素的hashCode值是否相同
    如果相同,还会继续判断元素的equals方法,是否为true
  --TreeSet:可以对Set集合中的元素进行排序。
    保证元素唯一性的依据:compareTo方法return 0

TreeSet排序的第一种方式:让元素自身具备比较性,元素需要实现Comparable接口,覆盖compareTo方法
  这种排序也称为元素的自然顺序,也叫默认顺序。
TreeSet排序的第二种方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的,这是就需要让集合自身具备比较性。
  在集合初始化时,就有了比较方式。

public class TreeSet_01 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        TreeSet ts=new TreeSet();
        
        ts.add("cba");
        ts.add("abcd");
        ts.add("aaa");
        ts.add("bbb");
        
        Iterator it=ts.iterator();
        while(it.hasNext()){
            sop(it.next());
        }
        /*
        aaa
        abcd
        bbb
        cba
         */
    }
    
    public static void sop(Object obj){
        System.out.println(obj);
    }

}

 

需求:往TreeSet集合中存储自定义对象学生。
  想按照学生的年龄进行排序

往TreeSet集合中存入对象,对象必须具备比较性

记住:排序时,主要条件相同时,一定要判断次要条件

public class TreeSet_02 {

    public static void main(String[] args) {
        TreeSet ts=new TreeSet();
        
        ts.add(new Student("lisa02",22));
        ts.add(new Student("lisa007",20));
        ts.add(new Student("lisa09",19));
        ts.add(new Student("lisa08",19));
        //ts.add(new Student("lisa01",40));
        
        Iterator it=ts.iterator();
        while(it.hasNext()){
            Student st=(Student) it.next();
            sop(st.getName()+"..."+st.getAge());
        }
    }
    
    public static void sop(Object obj){
        System.out.println(obj);
    }

}
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;
    }
    
    //负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。 
    public int compareTo(Object obj) {
        if(!(obj instanceof Student)){
            throw new RuntimeException("不是 学生对象");
        }
        Student st=(Student) obj;
        
        System.out.println(this.name+"...compareTo..."+st.name);
        if(this.age>st.age){
            return 1;
        }else if(this.age == st.age){
            //return 0; 名字不同, 年龄相同,返回0,被视为同一对象
            return this.name.compareTo(st.name);
        }else{
            return -1;
        }
    }
}

 

当元素自身不具备比较性,或者具备的比较性不是所需的。这时需要让容器自身具备比较性。
定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

当两种排序都存在时,以比较器为主。

定义一个类,实现Comparator接口,覆盖compare方法

public class Comparator_03 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TreeSet ts=new TreeSet(new MyCompare());
        
        ts.add(new Teacher("lisa02",22));
        ts.add(new Teacher("lisa007",20));
        ts.add(new Teacher("lisa09",19));
        ts.add(new Teacher("lisa08",19));
        
        ts.add(new Teacher("lisa007",33));
        
        //ts.add(new Student("lisa01",40));
        
        Iterator it=ts.iterator();
        while(it.hasNext()){
            Teacher st=(Teacher) it.next();
            sop(st.getName()+"..."+st.getAge());
        }
    }  
    
    public static void sop(Object obj){
        System.out.println(obj);
    }

}

class MyCompare implements Comparator{

    @Override
    public int compare(Object o1, Object o2) {
        
        Teacher t1=(Teacher) o1;
        Teacher t2=(Teacher) o2;
        
        int num=(t1.getName().compareTo(t2.getName()));
        
        if(num==0){
            /*if(t1.getAge()>t2.getAge()){
                return 1;
            }else if(t1.getAge()==t2.getAge()){
                return 0;
            }else{
                return -1;
            }*/
            
            //两种方式等价,Integer本身具备比较方法
            return new Integer(t1.getAge()).compareTo(new Integer(t2.getAge()));
        }
        
        return num;
    }
    
}

class Teacher implements Comparable{
    private String name;
    private int age;
    
    Teacher(String name,int age){
        this.name=name;
        this.age=age;
    }
    
    public String getName(){
        return name;
    }
    
    public int getAge(){
        return age;
    }
    
    public int compareTo(Object obj) {
        if(!(obj instanceof Teacher)){
            throw new RuntimeException("不是 学生对象");
        }
        Teacher st=(Teacher) obj;
        
        if(this.age>st.age){
            return 1;
        }else if(this.age == st.age){
            return this.name.compareTo(st.name);
        }else{
            return -1;
        }
    }
}

 

练习:按照字符串长度排序

字符串本身具备比较性,但是它的比较方式不是所需要的,这是就只能只用比较器

public class Comparator_04 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TreeSet ts=new TreeSet(new StringComparator());
        
        ts.add("abcd");
        ts.add("cc");
        ts.add("cba");
        ts.add("aaa");
        ts.add("z");
        ts.add("hahaha");
        
        Iterator it=ts.iterator();
        
        while(it.hasNext()){
            sop("字符串为:"+it.next());
        }
    }
    
    public static void sop(Object obj){
        System.out.println(obj);
    }

}
class StringComparator implements java.util.Comparator{

    @Override
    public int compare(Object o1, Object o2) {
        
        String s1=(String) o1;
        String s2=(String) o2;
        
        if(s1.length()>s2.length()){
            return 1;
        }else if(s1.length() == s2.length()){
            return s1.compareTo(s2);
        }else{
            return -1;
        }
    }
    
}

 

33.Set

标签:void   集合   同步   哈希   rgs   iter   完成   return   asn   

原文地址:https://www.cnblogs.com/syj1993/p/8335076.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!