黑马程序员-集合框架Collection的若干知识点

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

概述:

所有集合类都位于java.util包下。集合中只能保存对象(保存对象的引用变量)。(数组既可以保存基本类型的数据也可以保存对象)。

       当我们把一个对象放入集合中后,系统会把所有集合元素都当成Object类的实例进行处理。从JDK1.5以后,这种状态得到了改进:可以使用泛型来限制集合里元素的类型,并让集合记住所有集合元素的类型。

 Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些接口或实现类。Set和List接口是Collection接口派生的两个子接口,Queue是Java提供的队列实现,类似于List。

List:元素是有序的,元素可以重复,因为该集合体系有索引
ArrayList:底层的数据结构使用的是数组结构,查询速度很快,但是增删稍慢,线程不同步,默认10个元素
LinkedList:底层使用的链表数据结构,查询很慢,增删速度很快
Vector:底层是数组数据结构,和ArrayList一样,查询,增删,都很慢,Vector是1.0出现,ArrayList是1.2出现,线程同步,现在不用了。
Set:元素是无序的,元素不可以重复
HashSet
TreeSet
对于Set、List集合,最常用的实现类分别是HashSet、ArrayList这两个实现类。

下面重点介绍些关于list和set的重要知识点。

一 迭代器

其实就是集合的取出元素的方式
就把取出方式定义在集合的内部,这样取出方式就可以直接访问结合内容的元素。那么取出方式就定义成了内部类。
而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共共性内容:判断,取出。那么可以将写共性取出。
那么这些内部类都符合一个规则。该规则是Iterator。如何获取集合的取出对象呢?通过一个对外提供的方法:iterator);

ListIterator

1、list集合特有的迭代器,ListIterator是Iterator的子接口。
2、在迭代时候,不可以通过集合对象的方法操作集合中的元素,因为会发生ConcurrenModificationException异常。
3、所以在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作
4、如果想要其他的操作,如添加、修改等,就需要使用其子接口,ListIterator。
5、该接口只能通过List集合的listIterator方法获取
6、hasPrevious(),前面是否有元素

代码示例如下:

 import java.util.*;  

  class Demo{  

      public static void main(String[] args){  

          method_get();  

      }  

      public static void method_get(){  

          ArrayList al = new ArrayList();  

          al.add("java01");  

          al.add("java02");  

        al.add("java03");  

        al.add("java04");  

         sop("原集合是:"+al);  

         al.add(1,"java09");  

         sop("后:"+al);  

         //删除  

        al.remove(2);  

         //修改元素  

         al.set(2,"java07");  

         //通过角标获取元素  

         sop(al.get(1));  

         //获取所有元素  

        for(int x=0;x<al.size();x++){  

             sop("al("+x+") = "+al.get(x));  

         }  

         for(Iterator it = al.iterator();it.hasNext();){  

             sop(it.next());  

         }  

        //通过 indexOf获取对象的位置  

         sop(al.indexOf("java04"));  

         sop(al);  

         sop(al.subList(1,3));  

         ListIterator li = al.listIterator();  

           

     }  

    public static void sop(Object obj){  

        System.out.println(obj);  

     }  

 }  


二:List集合共性方法

List:特有方法,凡是可以操作角标的方法都是该体系特有的方法
(1)、增:
add(index,element)
(2)、删:
remove(index)
(3)、改:
set(index,element)
(4)、查:
get(index)
subList()
listIterator()

三:Vector中的枚举)
1、枚举就是Vector特有的取出方式
2、发现枚举和迭代器很像。
3、其实枚举和迭代是一样的,
4、因为枚举的名称以及方法的名称都过长,所以被迭代器取代了,枚举就郁郁而终了


  import java.util.*;  

  class Demo{  

      public static void main(String[] args){  

          method_get();  

     }  

      public static void method_get(){  

          Vector v = new Vector();  

         v.add("java01");  

         v.add("java02");  

        v.add("java03");  

         v.add("java04");  

         Enumeration en = v.elements();  

         while(en.hasMoreElements()){  

             sop(en.nextElement());  

         }  

     }  

     public static void sop(Object obj){  

        System.out.println(obj);  

    }  

 }  

四、LinkedList
1、LinkedList:特有方法
(1)、addFirst():
(2)、addLast():
(3)、getFirst():
(4)、getLast():
(5)、removeFirst():删除并返回元素,如果集合中没有有元素,会出现NoSuchElementExceptionextends RuntimeException 表明枚举中没有更多的元素。

peekFirst() 获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
(5)、removeLast()
2、1.6中出现了替代方法
boolean offer(E e) 

         将指定元素添加到此列表的末尾(最后一个元素)。 
boolean offerFirst(E e) 
          在此列表的开头插入指定的元素。 
E peekFirst() 
          获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。 
E peekLast() 
          获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。
E pollFirst() 
 获取并移除此列表的第一个元素;如果此列表为空,则返回 null。 
E pollLast() 
 获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。 

五、ArrayList

System.Collections.ArrayList类是一个特殊的数组。通过添加和删除元素,就可以动态改变数组的长度。

  一.优点

1. 支持自动改变大小的功能
2. 可以灵活的插入元素
3. 可以灵活的删除元素

  二.局限性

跟一般的数组比起来,速度上差些

  三.添加元素

1.publicvirtualintAdd(objectvalue);

将对象添加到ArrayList的结尾处

ArrayList aList = new ArrayList();
aList.Add("a");
aList.Add("b");
aList.Add("c");
aList.Add("d");
aList.Add("e");
内容为abcde

2.publicvirtualvoidInsert(intindex,objectvalue);

将元素插入ArrayList的指定索引处

ArrayList aList = new ArrayList();
aList.Add("a");
aList.Add("b");
aList.Add("c");
aList.Add("d");
aList.Add("e");
aList.Insert(0,"aa");

结果为aaabcde

3.publicvirtualvoidInsertRange(intindex,ICollectionc);

将集合中的某个元素插入ArrayList的指定索引处

ArrayList aList = new ArrayList();
aList.Add("a");
aList.Add("b");
aList.Add("c");
aList.Add("d");
aList.Add("e");
ArrayList list2 = newArrayList();
list2.Add("tt");
list2.Add("ttt");
aList.InsertRange(2,list2);

结果为abtttttcde

  四.删除

1. publicvirtualvoidRemove(objectobj);

从ArrayList中移除特定对象的第一个匹配项,注意是第一个

ArrayList aList = new ArrayList();
aList.Add("a");
aList.Add("b");
aList.Add("c");
aList.Add("d");
aList.Add("e");
aList.Remove("a");

结果为bcde

2. publicvirtualvoidRemoveAt(intindex);

移除ArrayList的指定索引处的元素

aList.Add("a");
aList.Add("b");
aList.Add("c");
aList.Add("d");
aList.Add("e");
aList.RemoveAt(0);

结果为bcde

3.publicvirtualvoidRemoveRange(intindex,intcount);

从ArrayList中移除一定范围的元素。Index表示索引,count表示从索引处开始的数目

aList.Add("a");
aList.Add("b");
aList.Add("c");
aList.Add("d");
aList.Add("e");
aList.RemoveRange(1,3);

结果为ae

4.publicvirtualvoidClear();

从ArrayList中移除所有元素。

 五.排序

a) publicvirtualvoidSort();

对ArrayList或它的一部分中的元素进行排序。

ArrayList aList=new ArrayList();
aList.Add("e");
aList.Add("a");
aList.Add("b");
aList.Add("c");
aList.Add("d");
DropDownList1.DataSource=aList;//DropDownListDropDownList1;
DropDownList1.DataBind();

结果为eabcd

ArrayList aList=new ArrayList();
aList.Add("a");
aList.Add("b");
aList.Add("c");
aList.Add("d");
aList.Add("e");
aList.Sort();//排序
DropDownList1.DataSource=aList;//DropDownListDropDownList1;
DropDownList1.DataBind();

结果为abcde

b) publicvirtualvoidReverse();

将ArrayList或它的一部分中元素的顺序反转。

ArrayList aList=new ArrayList();
aList.Add("a"); 
aList.Add("b");
aList.Add("c");
aList.Add("d");
aList.Add("e");
aList.Reverse();//反转
DropDownList1.DataSource=aList;//DropDownListDropDownList1;
DropDownList1.DataBind();
结果为edcba

  六.查找

a) publicvirtualintIndexOf(object);
b) publicvirtualintIndexOf(object,int);
c) publicvirtualintIndexOf(object,int,int);

    返回ArrayList或它的一部分中某个值的第一个匹配项的从零开始的索引。没找到返回-1。

    ArrayList aList = new ArrayList();
    aList.Add("a");
    aList.Add("b");
    aList.Add("c");
    aList.Add("d");
    aList.Add("e");
    intnIndex=aList.IndexOf(“a”);//1
    nIndex=aList.IndexOf(“p”);//没找到,-1
d) publicvirtualintLastIndexOf(object);
e) publicvirtualintLastIndexOf(object,int);
f) publicvirtualintLastIndexOf(object,int,int);

    返回ArrayList或它的一部分中某个值的最后一个匹配项的从零开始的索引。

    ArrayList aList = new ArrayList();
    aList.Add("a");
    aList.Add("b");
    aList.Add("a");//同0
    aList.Add("d");
    aList.Add("e");
    intnIndex=aList.LastIndexOf("a");//值为2而不是0

g) publicvirtualboolContains(objectitem);

    确定某个元素是否在ArrayList中。包含返回true,否则返回false

六、HashSet



  Set:元素是无序(存入和取出的顺序不一定一致)的,元素不可以重复 

     HashSet:底层数据结构是哈希表 

          HashSet是如何保证元素的唯一性的呢? 

         是通过元素的两个方法,hashCode和equals来完成。 

         如果元素的hashCode值相同,才会判断equals是否为true 

          如果元素的hashCode值不同,不会调用equals 

          

          注意:对于判断元素是否存在,以及删除的操作,以来的方法是元素的 hashCode和equals方法 

             先 hashCode 再 equals 

             而,arrayList 仅仅是equals 

     TreeSet: 

      

 Set集合的功能和Collection是一致的 

 */  

import java.util.*;  

 

  

 public class Demo{  

     public static void main(String args[]){  

         HashSet hs = new HashSet();  

        hs.add("java01");  

         hs.add("java02");  

         hs.add("java03");  

         sop(hs.add("java04"));  

         sop(hs.add("java04"));  

         for(Iterator it = hs.iterator();it.hasNext();){  

            sop(it.next());  

        }  

     }  

     public static void sop(Object obj){  

         System.out.println(obj.toString());  

     }  

}  



七:二叉树TreeSet


Set:无序,不可以重复元素 

     HashSet:数据结构是哈希表,线程是非同步 

       保证元素唯一的原理:判断元素的HashCode值是否相同。 

         如果相同,还会继续判断元素的equals方法,是否为true 

     TreeSet:可以对Set集合中的元素进行排序,按照Asiic 

          底层数据结构是二叉树 

          保证元素唯一性的依据 

         compareTo 方法 return 0,表明数据相同 

         

        TreeSet 排序的第一种方式:让元素自身具备比较性 

         元素需要实现 Comparable 接口,覆盖compareTo方法 

         这种方式也称为元素的自然顺序,或者默认顺序。 

     

需求:往 TreeSet 集合中存储自定义对象学生。 

 想按照学生的年龄进行排序 

 public interface Comparable<T>此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。 

如果返回0,表明这两个对象相等,不存储 

 


记住:排序时,当主要条件相同时,一定 判断一下次要条件 

HashSet如果是对象,需要重写equals,但是TreeSet存的时候会判断大小,相当于判断是否相当,所以不用重写equals 

  

如果想要按照存入书顺序取出 

可以让 compareTo 恒返回 1;这样存在于二叉树的右侧,就可以了 


import java.util.*;  

 

   

 public class Demo{  

     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("lisi02",40));  

        ts.add(new Student("lisi01",40));  

       for(Iterator it = ts.iterator();it.hasNext();){  

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

            sop(s.getName()+" :: "+s.getAge());  

         }  

          

      }  

     public static void sop(Object obj){  

          System.out.println(obj.toString());  

      }  

 }  

 class Student implements Comparable{  

     private String name;  

     private int age;  

      Student(String name,int age){  

         this.name = name;  

          this.age = age;  

      }  

      public String getName(){  

          return name;  

     }  

      public int getAge(){  

          return age;  

     }  

     //如果返回0,表明这两个对象相等,不存储  

     public int compareTo(Object obj){  

          if(!(obj instanceof Student)){  

              throw new RuntimeException("不是学生对象");  

         }  

          Student s = (Student)obj;  

          int num = this.age-s.age;  

         if(num==0){  

              return this.getName().compareTo(s.getName());  

          }else{  

             return num;  

         }  

     }  

 }  

另外:实现Comparator方式排序

 TreeSet的第二种排序方式 

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

      这时候需要让集合自身具备比较性 

      在集合初始化时,就有了比较方式。 

   定义一个比较器,将比较器对象作为参数,传递给 TreeSet 集合的构造函数 

    

   

  当两种方式都存在时候,以比较器为主 

此处代码略。


八: 泛型

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

  

    

  好处: 

  1、将运行时期出现的问题 classCastException,转移到了编译时期 

       方便于程序员解决问题。让运行时期问题减少,安全。 

   2、避免了强制转换的麻烦 

   

   

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

  什么时候使用泛型呢? 

  通常在集合框架中很常见 

 只要见到<>就要定义泛型 

  

  其实<>就是用来接收类型的。 

   

  当使用集合时,将集合中要存储的数据类型作为参数传递到尖括号中即可,和函数传参数一样 



 泛型类 

什么时候定义泛型类? 

  当类中要操作的引用数据类型不确定的时候 

  早起定义Object 来完成扩展 

   

现在,定义泛型来完成扩展。

代码如下:


  import java.util.*;  

    

   public class Demo{  

      public static void main(String args[]){  

           //泛型出现以前的做法  

           Tool t = new Tool();  

          //可以传入 worker  

           t.setObject(new Worker());  

          t.getObject();  

          //可以传入Student  

          t.setObject(new Student());  

          t.getObject();  

            

          //泛型出现以后的做法  

          Utils<Worker> u = new Utils<Worker>();  

          u.setObject(new Worker());  

         Worker w = u.getObject();  

      }  

      public static void sop(Object obj){  

          System.out.println(obj.toString());  

     }  

 }  

  class Worker{  

        

  }  

  class Student{  

        

  }  

  //泛型出现以前的做法  

  class Tool{  

     private Object o;  

     public void setObject(Object o){  

          this.o = o;  

      }  

      public Object getObject(){  

         return o;  

      }  

  }  

 //泛型出现后,用泛型的做法  

  //泛型类  

  class Utils<E>{  

     private E o;  

     public void setObject(E o){  

          this.o = o;  

    }  

      public E getObject(){  

          return o;  

      }  

  }  



九:泛型方法

  泛型类定义的泛型,在整个类中有效,如果被方法是用 

       那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了 

      

      为了让不同方法可以操作不同类型,而且类型还不确定 

    那么可以将泛型定义在方法上,而不定义在类上 

  public <T> void show(T t){ 

           

    } 

另外:静态方法泛型

泛型类中也可以定义泛型方法
特殊之处:静态方法不可以访问类上定义的泛型,因为只有在实例化的时候,才会使用泛型
如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上
<T> 泛型写在返回值前


public static <T> void setName(T t){
    
}      

泛型类代码示例:

   import java.util.*;  

    

   

  public class Demo{  

      public static void main(String args[]){  

         //泛型确定  

        GenericDemo<String> d = new GenericDemo<String>();  

        d.show("haha");  

         d.print("hehe");  

        //泛型不确定  

        GenericDemo_2 d_2 = new GenericDemo_2();  

          d_2.show("haha");  

          d_2.print(new Integer(4));  

       d_2.print(4);  

    }  

      public static void sop(Object obj){  

          System.out.println(obj.toString());  

      }  

  }  

  //类型已经确定  

  class GenericDemo<T>{  

      public void show(T t){  

         sop("show:"+t);  

      }  

      public void print(T t){  

          sop("print:"+t);  

      }  

      public static void sop(Object obj){  

          System.out.println(obj.toString());  

     }  

 }  

  //类型不确定,使用泛型方法  

 class GenericDemo_2{  

      //泛型方法  

     public <Q> void show(Q q){  

          sop("show_2:"+q);  

      }  

     public <Q> void print(Q q){  

          sop("print_2:"+q);  

     }  

      public static void sop(Object obj){  

         System.out.println(obj.toString());  

      }  

  }  


十:泛型限定

通配符

 

  import java.util.*;  

   public class Demo{  

      public static void main(String args[]){  

          ArrayList<String> al = new ArrayList<String>();  

           al.add("abc");  

          al.add("sadf");  

          al.add("sa");  

         ArrayList<Integer> al1 = new ArrayList<Integer>();  

           al1.add(1);  

          al1.add(2);  

          al1.add(3);  

        printColl(al);  

          printColl(al1);  

     }  

      public static void printColl(ArrayList<?> al){  

          Iterator<?> it = al.iterator();  

         while(it.hasNext()){  

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

          }  

      }  

  }  

   

  /* 

 ? 通配符 

 ? extends E:可以接收 E 类型或者 E 的子类型。上限。 

  ? super E:可以接收E类型或者E的父类型,下限 

 */  

  import java.util.*;  

 public class Demo{  

     public static void main(String args[]){  

         ArrayList<Person> al = new ArrayList<Person>();  

          al.add(new Person("abc"));  

         al.add(new Person("dsf"));  

          al.add(new Person("absdc"));  

            

         ArrayList<Student> al1 = new ArrayList<Student>();  

         al1.add(new Student("abc"));  

         al1.add(new Student("dsf"));  

          al1.add(new Student("absdc"));  

            

         //printColl(al1);这是错误的,不能直接写  

          

      }  

    //public static void printColl(ArrayList<Person> al){ 这样只能接受person  

     public static void printColl(ArrayList<? extends Person> al){//这样可以接收别的子类  

         Iterator<Person> it = al.iterator();  

         while(it.hasNext()){  

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

        }  

     }  

 }  

  class Person{  

     private String name;  

      Person(String name){  

          this.name = name;  

     }  

     public String getName(){  

          return name;  

     }  

  }  

 class Student extends Person{  

      Student(String name){  

         super(name);  

     }  

}



------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值