集合(Collection)

来源:互联网 发布:linux vi 如何编辑 编辑:程序博客网 时间:2024/06/06 00:12

第五章:集合(Collection)


一,List :元素是有序的,元素可以重复。因为该集合体系有索引。

ArrayList
底层是Object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点。
而在LinkedList的底层是一种双向循环链表。在此链表上每一个数据节点都由三部分组成:前指针(指向前面的节点的位置),数据,后指针(指向后面的节点的位置)。最后一个节点的后指针指向第一个节点的前指针,形成一个循环。
双向循环链表的查询效率低但是增删效率高。
ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。

LinkedList
经常用在增删操作较多而查询操作很少的情况下:队列和堆栈。
队列:先进先出的数据结构。
栈:后进先出的数据结构。
注意:使用栈的时候一定不能提供方法让不是最后一个元素的元素获得出栈的机会。

Vector
(与ArrayList相似,区别是Vector是重量级的组件,使用使消耗的资源比较多。)
结论:在考虑并发的情况下用Vector(保证线程的安全)。
在不考虑并发的情况下用ArrayList(不能保证线程的安全)。

知识点:
java.util.stack(stack即为堆栈)的父类为Vector。可是stack的父类是最不应该为Vector的。因为Vector的底层是数组,且Vector有get方法(意味着它可能访问到并不属于最后一个位置元素的其他元素,很不安全)。
对于堆栈和队列只能用push类和get类。
Stack类以后不要轻易使用。
实现栈一定要用LinkedList。
(在JAVA1.5中,collection有queue来实现队列。)

二,Set :无序,不可以重复元素。
|--HashSet:数据结构是哈希表。线程是非同步的。
保证元素唯一性的原理:判断元素的hashCode值是否相同。
如果相同,还会继续判断元素的equals方法,是否为true。
 
-HashSet实现类:
遍历一个Set的方法只有一个:迭代器(interator)。
HashSet中元素是无序的(这个无序指的是数据的添加顺序和后来的排列顺序不同),而且元素不可重复。
在Object中除了有finalize(),toString(),equals(),还有hashCode()。
HashSet底层用的也是数组。
当向数组中利用add(Object o)添加对象的时候,系统先找对象的hashCode:
这样的机制就导致两个相同的对象有可能重复地添加到数组中,因为他们的hashCode不同。
如果我们能够使两个相同的对象具有相同hashcode,才能在equals()返回为真。
在实例中,定义student对象时覆盖它的hashcode。
因为String类是自动覆盖的,所以当比较String类的对象的时候,就不会出现有两个相同的string对象的情况。
现在,在大部分的JDK中,都已经要求覆盖了hashCode。

结论:如将自定义类用hashSet来添加对象,一定要覆盖hashcode()和equals(),覆盖的原则是保证当两个对象hashcode返回相同的整数,而且equals()返回值为True。

hashSet的优点:
        hashSet的底层是数组,其查询效率非常高。而且在增加和删除的时候由于运用的hashCode的比较开确定添加元素的位置,所以不存在元素的偏移,所以效率也非常高。因为hashSet查询和删除和增加元素的效率都非常高。
但是hashSet增删的高效率是通过花费大量的空间换来的:因为空间越大,取余数相同的情况就越小。HashSet这种算法会建立许多无用的空间。
      使用hashSet类时要注意,如果发生冲突,就会出现遍历整个数组的情况,这样就使得效率非常的低。
/*
 
TreeSet:可以对Set集合中的元素进行排序。
           特点:底层数据结构是二叉树。
                     保证元素唯一性的依据:
                     compareTo方法return 0.
 
TreeSet排序的第一种方式:让元素自身具备比较性。
                     元素需要实现Comparable接口,覆盖compareTo方法。
                     也种方式也成为元素的自然顺序,或者叫做默认顺序。
 
TreeSet的第二种排序方式。
                    当元素自身不具备比较性时,或者具备的比较性不是所需要的。
                    这时就需要让集合自身具备比较性。
                   定义一个Comparator类,让他实现某种特定的比较方法。然后再去实现它,如下。public static Set getStudents(Comparator cmp)
                    在集合初始化时,就有了比较方式。
 

需求:往TreeSet集合中存储自定义对象学生。
      想按照学生的年龄进行排序。
      记住,排序时,当主要条件相同时,一定判断一下次要条件。
 
 class TreeSetDemo 
{
      public static void main(String[] args) 
     {
      TreeSet ts = new TreeSet();
 
      ts.add(new Student("lisi02",22));
      ts.add(new Student("lisi007",20));
      ts.add(new Student("lisi09",19));
      ts.add(new Student("lisi08",19));
      //ts.add(new Student("lisi007",20));
      //ts.add(new Student("lisi01",40));
 
      //迭代器遍历方法。必须掌握。
      Iterator it = ts.iterator();
            while(it.hasNext())
           {
                 Student stu = (Student)it.next();
                 System.out.println(stu.getName()+"..."+stu.getAge());
           }
       }
}
 
class Student implements Comparable//该接口强制让学生具备比较性。
{
     private String name;
     private int age;
 
     Student(String name,int age)
     {
         this.name = name;
         this.age = age;
     }
 
     public int compareTo(Object obj)//覆盖compareTo方法。
     {
         if(!(obj instanceof Student))
               throw new RuntimeException("不是学生对象");
          Student s = (Student)obj;
          System.out.println(this.name+"....compareto....."+s.name);
          if(this.age>s.age)
                   return 1;
          if(this.age==s.age)
          {
                 return this.name.compareTo(s.name);
          }
          return -1;
      }
      public String getName()
      {
          return name;
      }
      public int getAge()
      {
          return age;
      }
}



0 0
原创粉丝点击