黑马程序员----集合之2

---------------------- android培训 、 java培训 、 期待与您交流! ------------------


数组和集合的区别:

    数组是固定长度,集合是可变长度;
    数组中可以存储基本数据类型,集合只能存储对象。
集合类的特点:集合中用于存储对象;长度是可变的;集合可以存储不同类型的对象,但是不可以存储基本的数据类型值。
    1、集合的add方法的参数类型是object。以便于接受任意类型的对象。
    2、集合中存储的都是对象的引用(地址)。
迭代器用于集合的取出元素的方式。
java迭代器内部设计方式:
    集合的取出方式被定义成了内部类。而每一个容器的数据结构不同,所以取出的动作细节也不一样。但是都有共性的内容判断和取出。那么可以将写共性抽取。
    这些内部类都符合一个规则。该规则是Iterator.
    如何获取集合的取出对象呢?通过一个对外提供的方法。即iterator().
    在迭代时循环中next调用一次,就要hasNext判断一次。必须这样,要不容易产生NoSuchElementException
    for(Iterator it = al.iterator();it.hasNext();)
    {
        System.Out.Println(it.next());
    }
    比
    Iterator it = al.iterator();
    while(it.hasNext())
    {
        System.Out.Println(it.next());
    }性能优越,因为Iterator it = al.iterator();循环完了之后it仍在内存中出现。  
        
Collection 最常用的:ArrayList、LinkedList、HashSet、HashMap。
    |--List 有序,可重复。因为该集合体系有索引。当设计到很多增删时用LinkedList,其他的用ArrayList。
        |--ArrayList:
            底层的数据结构使用的是数组结构。线程不同步。特点:查询、修改速度很快,但是增删稍慢。
            ArrayList集合判断元素是否相同,依据的是元素的equals方法。list.contains(obj)比较是否包含的时候用的是equals方法。
            remove也都是调用的equals方法。其他集合(例如hashSet)于此不同。判断元素是否相同,数据结构不同,依赖的方法也不同。
        |--LinkedList:
            底层使用的是链表数据结构。特点:增删速度很快,查询慢。
        |--Vector:
            底层是数组数据结构。线程同步。增删查改都很慢。(不用)。
            有用的一个方法:Enumeration en = vector.elements();枚举就是Vector特有的取出方式。
            Vector支持枚举,别的集合方法只有迭代器。
    |--Set  无绪,不可重复。该集合中无索引。
        |--hashSet:
            底层数据结构是哈希表,线程非同步。
            HashSet是如何保证元素唯一性的呢?是通过元素的两个方法:hashCode和equals来完成。
            判断元素的hashcode值是否相同。如果相同,继续判断元素的equals方法,看其是否相同,如果都相同,则是同一个元素。
            当自定义对象往集合中存的时候,一般都要复写对象的hashCode和equals方法。
            HashSet对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
        |--TreeSet:
            保证元素唯一性的依据:compareTo方法的return 0.如果return的是0则认为相同。当主要元素比较完后一定要比较次要元素,要不容易丢失元素。
            
            可以对Set集合中的元素进行排序。
            TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖CompareTo方法。这种方式也成为元素的自然顺序(默认顺序)。
                         第二种方式:当元素自身不具备比较性,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。
                                在集合初始化时,就有了比较方式。定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
                                定义一个比较器,需要实现Comparator接口,覆盖compare方法。
            当两种排序都存在时,以比较器为主。
    
List集合特有的方法:凡是可以操作角标的方法都是该体系特有的方法。
    增:add(index,element);
        addAll(index,Collection);
        
    删:remove(index);
    
    改:set(index,element);
    
    查:get(index);
        subList(from,to);包含from不包含to.
        listIterator();
    List集合特有的迭代器:ListIterator是Iterator的子接口。
    
    在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentMOdificationException异常。
    所以,在迭代时,只能用迭代器方法操作元素,可是Iterator的方法是有限的,只能对元素进行判断,取出,删除操作;如果想要其他的操作如添加,删除等,
        需要使用其子接口:ListIterator。该接口只能通过List集合的ListIterator方法获取。



    
  LinkedList的特有方法:
    addFirst();
    addLast();
    
    getFirst();
    getLast();
    获取元素,但不删除元素,如果集合中没有元素,会出现NoSuchElementException
    
    removeFirst();
    removeLast();
    获取元素,但元素被删除,如果集合中没有元素,会出现NoSuchElementException
    
    在JDK1.6之后出现了替代方法:
    offerFirst();
    offerLast();
    
    peekFirst();
    peedLast();
    获取元素,但不删除元素,如果集合中没有元素,会返回null.
    
    pollFirst();
    pollLast();
    获取元素,但元素被删除,如果集合中没有元素,会返回null.
    
    使用LinkedList模拟一个堆栈或者队列的数据结构。
    
    堆栈:先进后出
    队列:先进先出
    class DuiLie{
        private LinkedList link;
        
        DuiLie(){
            link = new LinkedList();
        }
        
        public void myAdd(Object obj){
            link.addFirst(obj);
        }
        
        public Object myGet(){
            return link.removeLast();
        }
        
        public boolean isNull(){
            return link.isEmpty();
        }
    }
    
Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
    Set集合的功能和Collection是一致的。
    
集合要使用泛型:是一个安全机制。
    好处:
        1、将运行时期出现的问题ClassCsatException,转移到了编译时期。方便与程序员解决问题,让运行时的问题减少,提高安全。
        2、避免了强制转换麻烦。
    迭代器、比较器、集合中都可以使用泛型。    
    泛型在比较器中的应用:
    class LenComparator implements Comparator<String>{
        public int compara(String s1,String s2){
            int num = new Integer(s1.length()).comparaTo(new Integer(s2.length()));
            if(num == 0)
                return s2.compareTo(s1);
            return num;
        }
    }
    
    泛型类:
        什么时候定义泛型类? 当类中要操作的“引用”数据类型不确定时,可以定义泛型来完成扩展。
        
        泛型类的定义小例:
            class Utils<T>{
                private T t;
                public void setObject(T t){
                    this.t = t;
                }
                public T getObject(){
                    return t;
                }
                //泛型方法的定义
                public <T> void show(T t){
                    System.out.println("show:" + t);
                }
            }
            
        泛型方法的定义小例:
        静态方法不可以访问类上定义的泛型。
        如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。
            class Demo{
                public <T> void show(T t){
                    System.out.println("show:" + t);
                }
                public <Q> void print(Q q){
                    System.out.println("print:" +q);
                }
                public static <T> method(T t){
                    System.out.println("show:" + t);
                }
            }
            
        泛型定义在接口上:
            interface Inter<T>{
                void show(T t);
            }
            class InterImpl<T> implements Inter<T>{
                public void show(T t){
                    System.out.println("show:" + t);
                }
            }
            
        泛型的高级应用:
            泛型的限定:用于泛型扩展用的。(?是通配符)
                上限定:? extends E:可以接受E类型或者E的子类型。
                下限定:? super E:可以接受E类型或者E的父类型。
            
    
    
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值