黑马程序员----集合类(二)

来源:互联网 发布:国家知识产权局知乎 编辑:程序博客网 时间:2024/06/08 15:17
------- android培训、java培训、期待与您交流! ----------

 

46、             HashSet

1、问题:关于HashSet中怎样实现的没有重复的元素?

      只要在元素添加进集合时,判断出当前元素与集合中的某个元素hashCode相等,并且equals方法返回的值为true时,那么当前元素存在,就不可能添加到HashSet集合中。

2、问题:关于HashSet中元素是怎样存放的?

前面已经说过,集合中的元素是对象的引用。而不是对象。HashSet中的元素,在堆内存中存放的方式是按照哈希值来存放的(这些哈希值存放于内存中的哈希表中,与我们添加对象的顺序无关),不是我们添加数据的时候那种顺序。取值的时候也是按照哈希表中哈希值来取。

3、问题:当元素的哈希值相同时,两个对象相等吗?

当在HashSet对象中添加元素时候,如果两个对象的hashCode不相等,那么这两个对象一定不相等;如果hashCode相等的话(即位置相同),还要做一个判断:两个元素的对象是否相同。判断两个元素是否相同要用equals方法。

元素的地址值相等,而不是同一个对象的时候,会在哈希表的那个相同位置处顺延,再连接一个对象

两个元素的哈希值相等,两个对象不一定相等;如果两个元素相等那么它们的哈希值一定相等

示例代码:

package day29;

class A{

    publicint hashCode(){

             return 60;

    }

}

publicclass HashSetDemo1 {

    publicstaticvoid main(String args[]){

             A a1 =new A();

             A a2 =new A();

             //day29.A@3c^^^^^^day29.A@3c

             System.out.println(a1+"^^^^^^"+a2);

             System.out.println(a1==a2);//false

             System.out.println(a1.equals(a2));//false

    }

}

注意:HashSet对于判断元素是否存在,以及删除等操作,依赖的方法时元素的hashCodeequals方法;而ArrayList依赖的是equals方法

47、             TreeSet

1TreeSet的特点:

TreeSet可以排序,按照什么方式排序,没有人告诉它,所以让添加到TreeSet中的元素具备了比较性。

TreeSet的要求是:往里添加的元素必须具备比较性。

可以对Set集合中的元素进行排序。

里面添加的对象,都必须要实现Comparable接口

2TreeSet里数据是怎么存放的?

是根据二叉树结构来存放的。但是在比较的时候又是怎么比较的呢?二叉树在比较的时候会选择一个折中的节点,来加快比较速度。

需求:

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

注意:排序时,当主要条件相同时,一定要判断一下次要条件。

示例代码:

TreeSetDemo.java

package day29;

import java.util.TreeSet;

//实现该接口的目的就是让Student对象具备比较性

import java.util.Iterator;

class StudentimplementsComparable{

        private Stringname;

        privateintage ;

        public Student(String name,int age){

                  this.name = name;

                  this.age = age;

        }      

        public String getName() {

                  returnname;

        }

        publicint getAge() {

                  returnage;

        }

        publicint compareTo(Object obj){

                  /**

                   *整个compareTo函数中只用return 1的话,在取数据的时候

                   *就是按照添加对象的顺序取出

                   *整个compareTo函数中只用return-1的话,在取数据的时候

                   *就是按照添加对象的逆序取出

                   * */

                  if(!(objinstanceof Student)){

                           thrownew RuntimeException();

                  }

                  Student s = (Student)obj;

                  System.out.println(this.name+"…………compare…………"+s.name);

                  if(this.age>s.age){

                           return 1;

                  }

                  if(this.age==s.age){

                           if(this.name.compareTo(s.name)>0)

                                    return 1;

                           elseif(this.name.compareTo(s.name)<0)

                                    return -1;

                           return 0;

                  }

                  return -1;

        }

}

publicclass TreeSetDemo {

        publicstaticvoid main(String args[]){

                  TreeSet set =newTreeSet();

                  set.add(new Student("zhangsan02",22));

                  set.add(new Student("zhangsan007",20));

                  set.add(new Student("zhangsan09",19));

                  set.add(new Student("zhangsan08",19));

                  Iterator it = set.iterator();

                  while(it.hasNext()){

                           Student s = (Student)it.next();

                           System.out.println(s.getName()+"…………next"+s.getAge());

                  }

        }

}

48、             TreeSet的两种排序都存在时,以比较器为主

示例代码:

package day29;

/*当元素自身不具备比较性,或者具备的比较性不是所需要的。

 *这时需要让容器自身具备比较性。

 *定义了比较器,将比较器对象作为参数传递给TreeSet

 *集合的构造函数。*/

import java.util.Comparator;

import java.util.Iterator;

import java.util.TreeSet;

class Student2implementsComparable{

    private Stringname;

    privateintage ;

    public Student2(String name,int age){

             this.name = name;

             this.age = age;

    }      

    public String getName() {

             returnname;

    }

    publicint getAge() {

             returnage;

    }

    publicint compareTo(Object obj){

             /**

              *整个compareTo函数中只用return 1的话,在取数据的时候

              *就是按照添加对象的顺序取出

              *整个compareTo函数中只用return-1的话,在取数据的时候

              *就是按照添加对象的逆序取出

              * */

             if(!(objinstanceof Student2)){

                      thrownew RuntimeException();

             }

             Student2 s = (Student2)obj;

             System.out.println(this.name+"…………compare…………"+s.name);

             if(this.age>s.age){

                      return 1;

             }

             if(this.age==s.age){

                      if(this.name.compareTo(s.name)>0)

                                return 1;

                      elseif(this.name.compareTo(s.name)<0)

                                return -1;

                      return 0;

             }

             return -1;

    }

}

class MyComparatorimplementsComparator{

    publicint compare(Object obj1, Object obj2){

             Student2 s1 = (Student2)obj1;

             Student2 s2 = (Student2)obj2;

             int num =s1.getName().compareTo(s2.getName());

             if(num==0){

                      returnnew Integer(s1.getAge()).

                      compareTo(new Integer(s2.getAge()));

             }

             return num;

    }

}

publicclass TreeSetDemo2 {

    publicstaticvoid main(String args[]){

             TreeSet set =new TreeSet(new MyComparator());

             set.add(new Student2("zhangsan02",22));

             set.add(new Student2("zhangsan007",20));

             set.add(new Student2("zhangsan09",19));

             set.add(new Student2("zhangsan08",19));

             Iterator it = set.iterator();

             while(it.hasNext()){

                      Student2 s = (Student2)it.next();

                      System.out.println(s.getName()+"…………next"+s.getAge());

             }

    }

}

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

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

示例代码:

package day29;

/**按字符串长度进行比较

 * 注意隐含条件:长度相同时,就得判断内容*/

import java.util.Comparator;

import java.util.TreeSet;

import java.util.Iterator;

publicclass TestComparatorDome {

         publicstaticvoid main(String args[]){

                   TreeSet tree =new TreeSet(new StringComparator());

                   tree.add("sdfsdf");

                   tree.add("we");

                   tree.add("adfw");

                   Iterator it = tree.iterator();

                   while(it.hasNext()){

                            System.out.println(it.next());

                   }                

         }

}

class StringComparatorimplementsComparator{

         publicint compare(Object obj1 ,Object obj2){

                   String s1 =(String)obj1;

                   String s2 =(String)obj2;

                   /*本段代码貌似没有问题,但是隐藏的问题是:如果字符串长度相同,

                    * 但是字符串内容不同时会先毛病,应该改写

                   if(s1.length()>s2.length()){

                            return 1;

                   }

                   if(s1.length()<s2.length()){

                            return -1;

                   }

                   return 0;

                   */

                   int num =new Integer(s1.length()).compareTo(new Integer(s2.length()));

                   if(num==0){

                            return 0;

                   }

                   return num;

         }

}

 

------- android培训、java培训、期待与您交流! ----------
原创粉丝点击