黑马程序员———集合(上)

来源:互联网 发布:sql server 连接查询 编辑:程序博客网 时间:2024/06/02 03:10
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


 

集合类:

  • 为什么出现集合类?
     面相对象语言对事物的体现都是以对象的形式,所以为了方便对多个
     对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式

  • 数组和集合类同是容器,有何不同?
     数组虽然也可以存储对象,但长度是固定的,集合长度是可变的。
     数组中可以存储基本数据类型,集合只能存储对象。

  • 集合类的特点:
                      集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。

  • 为什么会出现这么多的容器呢?
因为每一个容器对数据的存储方式都不同
这个存储方式称之为:数据结构

集合中存放的不可能是对象,是内存地址值。
add方法的参数类型是Object。以便于接收任意类型的对象
Collection中的方法详见API文档和Collection.java文件。


======================================================
  • Collection(add,remove,contains,clear,iterator)
 
            / ArrayList:底层的数据结构使用的是数组数据结构。特点:查询速度快,但是增删稍慢。线程不同步(自己加锁)
  • ---List   LinkedList:底层的数据结构是链表数据结构特点:增删速度很快,查询速度稍慢。
            \ Vector:底层是数组数据结构。线程同步。被ArrayList所替代。(后期几乎不用)
          
           / HashSet:底层数据结构是哈希表
  • ---Set
         \ TreeSet:可以对Set集合中的元素进行排序。
                底层数据结构是二叉树
                保证元素唯一性的依据:compareTo方法
       
      
  |--List:元素是有序的,元素可以重复,因为该集合体系有索引
  |--Set:元素是无序的,元素不可以重复。
            
               所谓的无序就是存人和取出的顺序不一定一致。
                 Set集合的功能和Collection是一致的。
      
  •        List:
            凡是带角标的都是List集合的特有方法
            
                 add(index,element);
                 addAll(index,Collection);
            
                 remove(index);
            
                 set(index,element);
            : 
                 get(index);
                 subList(from,to);
                 listIterator();     
                
  •        Set:有关知识点在下面

  • 其他
     ArrayList可变长度数组,构造一个初始容量为10的空列表,若大于10,则以50%增加容量。
     Vector:100%增加容量。
     最常见的集合:ArrayList     LinkedList      HashSet     HashMap
    
===================================================
  • 迭代器中的方法摘要:
boolean hasNext();
     如果仍有元素可以迭代。则返回true。
E     next();
     返回迭代的下一个元素。
void     remove();
     从迭代器指向的collection中移除迭代器返回的最后一个元素(可选操作)


把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内容的元素。
那么取出方式就被定义成了内部类。

而每一个容器的数据结构不同,所以取出的动作细节也不一样。但是都有共性内容:
判断和取出。那么可以将这些共性抽取。

那么,这些内部类都符合一个规则。该规则是Iterator

如何获取集合的取出对象呢?
通过一个对外提供的方法:iterator();

可以联想商场中夹娃娃的机器。

什么是迭代器呢?
     就是集合的取出元素的方式。


List集合特有的迭代器,ListIterator是Iterator的子接口。
     在迭代时,不可以通过集合对象的方法操作集合中的元素。
     因为会发生ConcurrentModificationException异常。

所有,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的。
     只能对元素进行判断和取出,删除的操作。
    
如果想要其他的操作如:添加,修改等,就需要使用其子接口:ListIterator。
     该接口只能通过List集合的listIterator方法获取。

               在迭代时,循环汇中next调用一次,就要hasNext判断一次。不能调用两次next();

===========================================================================


  • List集合判断元素是否相同,依据的是元素的equals方法。

     复写父类的equals方法,而集合中的contains方法其实就是调用底层的equals方法。
     remove的底层其实也是调用equals方法。
    
boolean contains(Object o)
     如果此colletion包含指定的元素,则返回true。更确切的讲,当且仅当此collection至少包含一个满足
     (o==null?e==null:o.equals(e))的元素e时,返回true。


  • LinkedList集合和其他集合区别不大,但有其特有的方法:
添加元素:
     addFirst();
     addLast();
获取元素:
     getFirst();
     getLast();
移除元素:
     removeFirst();
     removeLast();

当使用以上操作,但没有元素时,会出现:
NoSuchElementException:没有这个元素异常

  • 在JDK1.6出现了替代方法:
添加元素:
     offerFirst();
     offerLast();
获取元素:
     peekFirst();
     peekLast();
移除元素:
     pollFirst();
     pollLast();

当以上操作的列表为空时,既集合中没有元素,会返回null。

=====================================================
  • 接口:Enumeration<E>,此接口与Iterator接口的功能是重复的,此外,Iterator多了一个可选的移除操作,且方法名较短。
新的实现应该考虑Iterator接口而不是Enumeration
elements();
枚举就是Vector特有的取出方式。
发现枚举和迭代器很像。

其实枚举和迭代是一样的。
因为枚举的名称以及方法的名称都过长。
所以被迭代器取代了,枚举郁郁而终。

=====================================================

  • |--Set:元素是无序的,元素不可以重复
            所谓的无序就是存人和取出的顺序不一定一致。
            Set集合的功能和Collection是一致的。

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

               首先判断hashCode是否相同,若相同,会再次判断是否为同一个对象(使用equals方法)

注意:对于判断元素是否存在contains以及删除remove等操作都是依赖于元素的hashCode和equals方法。
     而在ArrayList依赖的只有equals


 Set:无序,元素不可以重复。
 ---HashSet:数据结构是哈希表。线程非同步。
                 保证元素唯一性的原理:hashCode和equalshashCode若相同,则继续判断equals,是否为true。
 
 ---TreeSet:可以对Set集合中的元素进行排序。
                底层数据结构是二叉树
                保证元素唯一性的依据:compareTo方法return 0.
                remove。contains等判断依据都是compareTo。
                
           TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法
                这种方式也称为元素的自然顺序或者叫做默认顺序。
           TreeSet排序的第二种方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。在集合初始化时,就有了比较方式。
                
           Comparable接口:有compareTo方法,返回类型是 int
|--------------------------------------------------------------|
|TreeSet()                                                                         |
|       构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。                 |
|TreeSet(Collection<? extends E> c)                                |
|   构造一个包含指定 collection 元素的新 TreeSet,它按照其元素的自然顺序进行排序。     |
|TreeSet(Comparator<? super E> comparator)                               |
|       构造一个新的空 TreeSet,它根据指定比较器进行排序。                             |
|--------------------------------------------------------------|
 

 当元素自身不具备比较性,或者具备的比较性不是所需要的。这时需要让容器自身具备比较性。
     定义比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
 
 当两种排序都存在时,以比较器为主。
     定义一个类实现Comparator接口,覆盖compare方法。
 
 整数类型Integer也具备比较性也实现Comparable接口。

 Set:无序,元素不可以重复。
---HashSet:数据结构是哈希表。线程非同步。
               保证元素唯一性的原理:hashCode和equals。hashCode若相同,则继续判断equals,是否为true。

---TreeSet:可以对Set集合中的元素进行排序
               底层数据结构是二叉树。
               保证元素唯一性的依据:compareTo方法return 0.
               remove。contains等判断依据都是compareTo。
              
          TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。
               这种方式也称为元素的自然顺序或者叫做默认顺序。
          TreeSet排序的第二种方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。在集合初始化时,就有了比较方式。

              
          Comparable接口:有compareTo方法,返回类型是int。
|--------------------------------------------------------------|
|TreeSet()                                                                     |
|       构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。                   |
|TreeSet(Collection<? extends E> c)                                  |
|   构造一个包含指定 collection 元素的新 TreeSet,它按照其元素的自然顺序进行排序。     |
|TreeSet(Comparator<? super E> comparator)                             |
|       构造一个新的空 TreeSet,它根据指定比较器进行排序。                            |
|--------------------------------------------------------------|

 
 
  需求:
       往TreeSet集合中存储自定义对象学生。
       想按照学生的年龄进行排序。
      
记住:排序时,当主要条件相同时,一定要判断次要条件。
     (而在次要条件中,判断姓名不适合用equals和==,因为这个只是比较是否同一个对象或者内存地址值是否相同,
     由于还需要排序,所以用compareTo方法,继续判断。)
    

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

当两种排序都存在时,以比较器为主。
     定义一个类实现Comparator接口,覆盖compare方法。

整数类型Integer也具备比较性也实现Comparable接口。




泛型:JDK1.5以后出现的新特性,用于解决安全问题,是一个类型安全机制。

          int[] arr = new int[3];
          arr[0] = 1;
          //arr[1] = 3.5;//编译失败,因为数组在创建时就已经明确了类型。
          而容器在创建时没有明确类型,容易有安全隐患。这时可以使用泛型来明确容器的类型。
         
好处:
     1.将运行时期出现问题ClassCastException,转移到了编译时期。
          方便于程序猿解决问题,让运行时期问题减少,安全
     2.避免了强制转换的麻烦。

泛型格式:通过<>定义要操作的引用数据类型

在使用java提供的对象时,什么时候使用泛型呢?
             通常在集合框架中很常见,只要见到<>就要定义泛型。

其实<>就是用来接收类型的。
     当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。



泛型定义在类上:

什么时候定义泛型类?
     当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展。
     现在定义泛型来完成扩展。


泛型定义在方法上:

泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所以要操作的类型就已经固定了。

class Demo<T>
{
     public void show(T t)
     {
          System.out.println("show "+t);
     }
     public void print(T t)
     {
          System.out.println("print "+t);
     }
}

为了不让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。

特殊之处:
     静态方法不可以访问类上定义的泛型。
     如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。

class Demo <Q>
{
     public <T> void show(T t)//泛型定义在方法上,可以操作不同类型
     {
          System.out.println("show "+t);
     }
    
     public void print(Q t)//泛型类定义的泛型在整个类中有效
     {
          System.out.println("print "+t);
     }
    
     public static <W> void method(W t)
     {
          System.out.println("method "+t);
     }
}

泛型定义在接口上。

     通配符            也可以理解为占位符。     
    
   泛型限定:    
   <? extends E>:可以接收E类型和E的子类型。上限。
   <? super E>:可以接收E类型或者E的父类型。下限。

  
       只打印Person和Person的子类  用  <? extends Person>


 

 

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


 

0 0
原创粉丝点击