黑马程序员技术交流社区

标题: 集合 上 ---->小尾巴梦工厂 [打印本页]

作者: 柒月份的尾巴丶    时间: 2016-7-27 22:02
标题: 集合 上 ---->小尾巴梦工厂
1.HashSet:元素无重复,无索引,存元素的顺序和取元素的顺序不一定一致
   唯一性原理:hashCode(),equals()
   规则:
     新素调用hashCode()方法与集合中已有的老元素调用hashCode()方法去比较

     比较结果不同:直接确定新元素与老元素不是一个元素,添加HashSet集合
     比较结果相同:再去调用equals方法去比较元素你属性值
                  如果equals返回true:说明两个元素的属性值均相同,我们就不在存储新元素
                  如果equals返回false:说明两个元素的属性值有不相同,我们就存储新元素
2.增强for循环(JDK1.5)
   for(集合/数组中元素的类型 变量名: 集合或数组对象){
       //该变量中存储每次遍历到的元素
      
   }
   增强for底层使用的是迭代器:
   使用迭代器步骤:
    ArrayList<String> al=new ArrayList<String>();
    al.add("张三");
    al.add("李四");
    Iterator<String> it=al.iterator()//1.获取迭代器对象
    while(it.hasNext()){//判断集合中是否有下一个元素
                       //底层的指针不会移动
                      //true说明集合有下一个元素

               System.out.println(it.next());//取出当前指针指向的元素,并且指针后移
    }
   并发修改异常:
     产生原因:在使用迭代器遍历的集合时候,使用集合自身的方法去添加/删除会报ConcurrentModificationException
     解决方案:
           1.不使用迭代器遍历集合
              for(int i=0;i<al.size();i++){
                      al.get(i);
                      al.add("3")
              }
           2.使用迭代器的方法来完成添加/删除
             如果需要添加使用ListIterator来完成遍历



3.集合体系:
a.单列集合Collection
        List:元素有序、包含重复元素、可使用索引
                ArrayList:底层数据结构是数组结构,增删慢,查询快。//有序的,可以重复,有索引,增删慢,查询快。
                LinkedList:底层是链表数据结构,增删快,查询慢.
                Vector:底层数据结构是数组结构,已被ArrayList替代。               

        Set:不包含重复元素
                HashSet:通过Hash表结构判断元素唯一性。
b.数组数据结构
   1.为什么数组查询快?
    因为数组中有索引直接利用get(int index)直接取元素
   2.为什么增删慢?
      数组角标 0  1  2  3  4
      元素     a  b  c  d  e
      删除c:   a  b  d  e  null

      结论:每删除一个元素,删除的元素后面的元素都要逐个向前移动一位
           假如要删除的元素后面有10000个元素,这10000个元素都需要向前移动一位,导致效率低下

      数组角标 0  1  2  3  4
      元素     a  b  c  d  e
   
    添加之前开辟一个长度为6的数组:
                   0  1  2  3  4  5
     元素          a  b  c  d  e  
   在2位置添加f:   a  b  f  c  d  e

     如果添加的元素已经超过数组的长度,新开辟一个数组对象,将原有数组的元素拷贝到新数组中,在添加元素
     如果数组长度不够用,我就要new新数组,开辟数组和拷贝元素都导致效率低下
c.链表数据结构
   1.为什么链表查询慢?
     每次查找都需要从链头开始比较,效率比较低
   2.为什么链表增删块?
     因为每次删除不需要移动大量元素,只需要改变元素的记录的地址值就行了


4.泛型:
   a.泛型的优点:
     1.使用泛型可以避免强转麻烦
     2.不使用泛型在运行时防止出现类型转换异常(ClassCastException)

   b.泛型使用位置:
     1.在类上使用:当创建这个类的对象时候,确定泛型的实际类型
       class Test<E,....>{//...代表泛型可以有多个,用,隔开
        private E e;      //类上定义在泛型可以在类中使用(变量和方法)
        public E method(E e){
           return null;
        }


       }
      Test<String>=new  Test<String>();//E的类型被确定为String,所有用到E的地方都是String类型
    2.在方法上使用:当调用method()方法时,传入什么类型T就是什么类型
       class Test{//...代表泛型可以有多个,用,隔开
        
         public <T> void method(T t){ //在方法返回值前面定义泛型,然后才能使用(形参,返回值,方法内部)


         }

       }
    3.再接口上定义泛型:
      interface Father<T>{
              void method(T t);
      }
      class Son implements Father<String>{//在实现父接口时直接确定泛型的类型,那么方法中用到的接口上的泛型也被确定
               public void method(String t){

               }
      }
      class Son2<T> implements Father<T>{//在实现父接口时不能直接确定泛型的类型,在创建Son2()的对象确定T的类型

         void method(T t){

         }

      }
      Son2<String>son=new Son2<String>();
    4.泛型通配符: ?
      ? extends E : ?的类型是E类型或E的子类型
      ? super E:?为E类型或者E的父类型
      
      public class Demo04<T> {

              public static void main(String[] args) {
                     
             Collection<String> c = new ArrayList<String>();
                   c.add("baby");
                       c.add("柳岩");
                       c.add("林允");
                     
                      ArrayList<CharSequence> list = new ArrayList<CharSequence>(c);//ArrayList(Collection<? extends E> c)
                                                                                                                                 //在new ArrayList<CharSequence>()确定了E的类型为
                                                                                   //E的类型为CharSequence
                                                                                   //ArrayList(Collection<? extends CharSequence> c)
                                                                                  // 把new ArrayList<String>(); 传递给ArrayList的构造函数


                      System.out.println(list);
                                                                                 
                      Demo04<Son> demo=new Demo04<Son>();//public void method(ArrayList<? super T> al)的T被确定为Son
                      ArrayList<Father> al=new ArrayList<Father>();
                  demo.method(al);//new ArrayList<Father>() 传给 method(ArrayList<? super Son> al)
                                  //Father代替?
                                  //Father super Son,Father是Son的父类型OK 没问题
                     
              }               
              public void method(ArrayList<? super Son> al){
                                                            
              }
      }




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2