黑马程序员_JAVA学习日记_JAVA中API:集合框架1(Collection,List,Set及其子类和迭代器的应用)

时间:2021-10-04 19:35:25

 

黑马程序员-学习日记

 

黑马程序员_JAVA中集合框架1(Collection,List,Set及其子类和迭代器的应用)

 

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

 

一:集合是用于存储对象的一个工具。

集合和数组的特点:

1.相同点:

       集合和数组都一个容器。

2.集合:

    1,可以存储对象,只能存储对象。

    2,集合的长度的是可变的。

3.数组:

    1,可以存储对象,也可以存储基本数据类型值。

    2,数组长度的是固定的。

注意:CollectionDemo.java 使用了未经检查或不安全的操作。注意:要了解详细信息,请使用 -Xlint:unchecked 重新编译。

Java编译器认为该成存在安全隐患。友情提示:但并不是编译失败,所以可以不用理会。

其实是因为类型的原因导致的,用了泛型以后,就没有该提示了。

二:集合中的一般方法:

importjava.util.*;

classCollectionDemo{

      public static void main(String[] args){

       Collection coll = new ArrayList();//创建了一个集合对象.也就是一个容器。

       //添加元素。add();

       coll.add("abc1");

       coll.add("abc2");

       coll.add("abc3");

       System.out.println("集合的元素:"+coll);

       //删除元素。

       boolean b =coll.remove("abc2");

       System.out.println("b="+b);

       //获取集合的长度。

       int size = coll.size();

       System.out.println("size="+size);

       //清除集合中的所有元素。

       coll.clear();

       //判断:

       boolean b = coll.isEmpty();//其实内部依据的是size()方法。如果size()=0,就返回true。

       System.out.println("b="+b);

       boolean b=coll.contains("abc1");

       System.out.println("b="+b);

       //简单的获取集合所有元素。直接将集合的元素打印到控制台。

       System.out.println("操作后的集合:"+coll);

       }

}

三:Collection中带All的方法用法集合:

  import java.util.*;

  class CollectionDemo2 {

       public static void main(String[] args) {

       Collection coll = new ArrayList();//创建了一个集合对象.也就是一个容器。      

       coll.add("abc1");

       coll.add("abc2");

       coll.add("abc3");

       System.out.println("集合的元素:"+coll);         

       Collection co2 = new ArrayList();

       co2.add("abc3");

       co2.add("abc2");

       co2.add("abc1");

       co2.add("abc4");

       Collection co3 = new ArrayList();

       co3.add("abc7");

       co3.add("abc8");

       //添加一堆元素。

       //coll.addAll(co2);//将co2中的元素添加到coll集合中。[abc1, abc2, abc3, abc5, abc]

       //判断一堆元素是否存在。

       boolean b = coll.containsAll(co3);

       System.out.println("b="+b);

       //删除一堆元素。

       boolean b1 =coll.removeAll(co3);//removeAll会将coll中包含的和co3相同的元素删除。

       System.out.println("b1="+b1);   

       //获取两个集合的交集。

       boolean b=coll.retainAll(co2);//retainAll会将coll和co2中相同的元素保留在coll中。

       //所以coll中存储就是交集的元素。当coll集合中的元素变化时,retainAll方法返回true。

       //当coll集合中的元素本身就是交集元素,不发生变化。那么返回false。

       System.out.println("b="+b);

       System.out.println(coll);

       }

}

四:Collection集合中对元素的获取方法:

 import java.util.*;

 class IteratorDemo{

        public static void main(String[] args) {

       Collection coll = new ArrayList();

       coll.add("abc1");

       coll.add("abc2");

       coll.add("abc3");

    //只要是Collection集合体系,迭代器就是通用取出方式。

       /*

       Iterator it = coll.iterator();

       while(it.hasNext()){

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

       }

       */

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

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

       }

    }

}

五:LinkedList的特有方法:

1:addFirst();

 addLast();

 在jdk1.6以后被

 offerFirst();

 offerLast();替代

2:获取元素,集合的长度不改变:

如果集合中没有元素,那么该方法会发生异常NoSuchElementException

getFirst():

getLast();

在jdk1.6以后被

peekFirst();

peekLast();替代

如果集合元素没有,该方法不会抛出异常,而是返回null。

3:获取元素,但是该元素会被删除出集合,集合的长度会改变:

如果集合中没有元素,那么该方法会发生异常NoSuchElementException

removeFirst():

removeLast();

在jdk1.6以后被:

pollFirst();

pollLast();替代

如果集合元素没有,该方法不会抛出异常,而是返回null。

import java.util.*;

class LinkedListDemo {

      public static void main(String[] args) {

       LinkedList  link = new LinkedList();

       link.addFirst("abc1");

       link.addFirst("abc2");

       link.addFirst("abc3");

       link.addFirst("abc4");

       System.out.println(link.getFirst());

       System.out.println(link.removeFirst());

       System.out.println(link);

       while(!link.isEmpty()){

              System.out.println(link.removeFirst());

       }

       }

}

六:List集合中常见的共性方法:List:该容器的元素是有序的(存储的顺序和取出的顺序一致)       该集合中的元素都有索引(角标).该集合可以存储重复的元素。

1,添加元素:add();

2,删除元素:remove();

3,修改元素: set();

4,获取元素:get();

import java.util.*;

class ListDemo{

      public static void main(String[] args){

       List list = new ArrayList();

       list.add("abc1");

       list.add("abc2");

       list.add("abc3");

       System.out.println("原集合:"+list);

       //添加功能。在指定位置插入元素。

       list.add(1,"haha");//在1索引为插入元素 haha.其他元素依次顺延。        

       //按照指定索引删除元素。会返回被删除的元素。

       System.out.println("remove(1):"+list.remove(1));

       //最指定位置的元素进行修改。会返回被修改掉的元素.

       System.out.println("set(0,kk)="+list.set(0,"kk"));

       //通过索引获取指定元素。

       System.out.println("get(1):"+list.get(1));

       //通过元素获取到第一次出现位置。

       System.out.println("indexOf(abc2)="+list.indexOf("abc2"));

       //根据头尾角标获取子列表。

       List newList = list.subList(0,2);//全取list.subList(0,list.size());

       System.out.println("自列表是:"+newList);

       //通过List特有的方式,获取集合中所有的元素。

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

              System.out.println(list.get(x));     

       }

       System.out.println("操作后:"+list);

     }

}

七:List:有序,可重复,有索引:

       |--ArrayList:底层数据结构是数组结构。线程不安全的。所以ArrayList的出现替代了Vector.但是查询的速度很快.

       |--Vector:底层数据结构是数组结构。jdk1.0版本。线程安全的。无论增删还是查询都非常慢。

       |--LinkedList:底层是链表数据结构。线程不安全的,同时对元算的增删操作效率很高

可变长度的数组:

       ArrayList内部封装了一个默认长度为10的数组;当超出长度时,集合内部会自动生成一个新的数组;将原数组中的元素复制到新数组中,在将新元素添加到新数组。

新数组的长度:

       ArrayList 50%延长。

       Vector 100%延长。

   Vector中提供了一个独特的取出方式,就是枚举Enumeration;此接口Enumeration的功能与 Iterator 接口的功能是重复的

   Enumeration的名称和方法的名称过程,书写很麻烦;所以被Iterator所取代,郁郁而终。

 import java.util.*;

 class VectorDemo{

      public static void main(String[] args) {

       Vector v = new Vector();

       v.addElement("abc1");

       v.addElement("abc2");

       v.addElement("abc3");

       v.addElement("abc4");     

       Enumeration en = v.elements();

       while(en.hasMoreElements()){

              System.out.println(en.nextElement());

       }

       Iterator it = v.iterator();

       while(it.hasNext()){

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

       }

     }

}

八:列表迭代器的应用:

    在进行迭代过程中,如果出现了迭代器和容器同时对元素进行操作的情况很容易引发ConcurrentModificationException并发修改异常.

    解决:要么使用集合的方法操作元素,要么使用迭代器的方法操作元素;不要同时使用。

    但是 迭代器Iterator中只有三个操作,判断hasNext,获取next,删除remove。

    想要其他的操作时,比如添加,这个迭代器就不可以使用了。这时对于List集合,有一个新的迭代方式, 就是ListIterator 列表迭代器。

    ListIterator本身也是Iterator的子接口。并提供了更多的迭代过程中的操作在迭代过程中,如果需要增删改查元素的操作,需要列表迭代器。

    但是注意:该迭代器,只能用于List集合。

 import java.util.*;

 class ListIteratorDemo{

      public static void main(String[] args) {                    

       List list = new ArrayList();

       list.add("abc1");

       list.add("abc2");

       list.add("abc3");

       list.add("abc4");

       ListIterator  lit = list.listIterator();

       System.out.println(lit.hasPrevious());

       while(lit.hasNext()){

              String s = (String)lit.next();

              if(s.equals("abc2"))

                     //lit.add("haha");

                     lit.set("qq");

              }

              System.out.println(list);

              System.out.println(lit.previous());

              Iterator it = list.iterator();

              while(it.hasNext()){

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

                     if(s.equals("abc2"))

                            list.add("haha");//ConcurrentModificationException

                     System.out.println("s="+s);

              }

              System.out.println(list);

       }

}

九:List和Set的用法区别:

A.|--List:有序(存的顺序和取的顺序一致。),元素可以重复,元素都有索引。

       |--ArrayList:

       |--LinkedList:

|--Set:无序,不可以重复元素。Set接口的方法和Collection中的方法一致。

       Set接口取出元素的方法只有迭代器。

       |--HashSet:底层数据结构是哈希表。哈希表这种结构,其实就是对哈希值的存储。

       而且每一个对象都有自己的哈希值。因为Object类中的有一个方法hashCode方法。

B.如何保证元素唯一性的呢?

通过判断元素的hashCode方法,和equals方法完成的;

当hashCode值相同是,会在判断一次euqals方法的返回只是是否为true。

       如果hashCode值不相同,就确定元素的哈希表中的位置,就不用在判断equals了。

       当哈希表中有一个桶结构。每一个桶都有一个哈希值,当哈希值相同,但是equals为false时,表示为不同元素。

       原理:这些元素都存放一个桶里。

|--TreeSet:可以对Set集合中的元素进行排序:

       数据结构是二叉树数据结构。这种结构,可以提高排序性能。

       1.它又是如何保证元素唯一性的呢?

是根据比较方法的返回值确定的:只要返回的是0,就代表元素重复。

   2.HashSet集合保证元素唯一性的原因:

HashSet集合保证元素唯一性,依赖的是元素的hashCode方法和euqals方法。

   当元素的哈希值不同时,元素都有自己的独立位置,不需要在判断元素的equals方法;

   3.当元素的哈希值相同时,这时元素在哈希表中位置相同,这时就需要在判断一次元素的内容是否相同;就需要调用元素的equals方法进行一次比较。如果equals返回是true,那么视为两个元素为重复元素,只储存一个。如果返回是false,那么这两个元素不是重复元素,会存储在同一个哈希值上。

  4.为了建立自定义对象判断元素是否重复的依据:

需要覆盖hashCode方法,和equals方法:而且最好依据对象的特有条件来建立hashcode和euqals的实现。

  ArrayList:判断包含,以及删除,都是依据元素的equals方法。

  HashSet:判断包含,以及删除,都是依据元素的hashCode方法。当hashCode值相同时,在判断一次equals方法。

实用小技巧:

   ArrayList: 数组

       LinkedList:链表

       HashSet:哈希表

       TreeSet:二叉树    

       看到Array就要想到数组,就要想到角标,就要想到查询很快.

       看到Link就要想到链表.就要想要增删很快.最好再想到 addFirst(offerFirst)

       看到Hash就要想要哈希表,就要想到元素的hashCode方法,和equals方法。

     看到Tree,就要想要二叉树,就要想要排序。就要想到两个接口 Comparable 和Comparator。

       需要明确的是什么时候List,什么时候用Set?

       保证元素唯一,就用Set集合;不需要就使用List集合;实在搞不清楚,就用ArrayList。

   Treeset集合使用于给元素进行排序的;那么自定义元素本身不具备比较性,Treeset集合是无法对元素进行排序的;

   所以,在自定义对象时,需要对象具备一个扩展功能,用于比较的,

   而java已经提供了接口,可以让实现它的对象具备比较性;那么自定义类,要想被Treeset排序,就需要实现Comparable接口;以具备比较功能。

比较的时候,要注意,主要条件和次要条件;如果主要条件相同,一定要比较次要条件。

  当Treeset集合中存储的元素不具备比较功能;或者具备的比较功能不是所需要的。

例如:Person对象中的自然排序是按照年龄排序。

  但是现在需求是想安装姓名排序。该源代码这种方式想都不要想。有这种想法就是犯罪。

  该如何解决这个问题?

既然元素具备的比较方式不满足应用;这时,可以让集合自身具备比较性。

需要集合一初始化就具备比较功能。因为要在添加元素前具备。

就需要在构造函数进行初始化。

只要将一个实现了Comparator接口的子类对象作为参数传递给TreeSet集合的构造函数即可。

这样该集合就具备了比较功能。

建议使用第二种排序方式。

应用:

TreeSet排序方式有两种。

1,让元素自身具备比较性。

        其实是让元素实现Comparable接口,覆盖compareTo方法。

       这称为元素的自然排序。

 

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

       可以让集合自身具备比较性。

       定义一个比较器:

       其实就是定义一个类,实现Comparator接口。覆盖compare方法。

       将Comparator接口的子类对象作为参数传递给TreeSet的构造函数。

       当元素自身具备比较性,同时TreeSet集合也具备比较器,这时以比较器为主。

十:学习了这么多,来一个总体总结:

一般在描述一个对象时,如果该对象封装了具体的数据,会出现很多这样的对象比如:员工,学生对象等.

这时就需要进行容器的存储.那么描述该类对象时,一定要复写几个方法:

1,hashCode()

2,equals()

3,toString()

4,最好实现Comparable接口让该类具备自然排序功能。

建立对象自身判断是否相同的依据,同时让对象具备基本的比较性。

代码体现:

class TreeSetDemo3{

      public static void main(String[] args) {

       TreeSet ts = new TreeSet(newCompareByName());

       ts.add(new Person("lisi1",21));

       ts.add(new Person("lisi4",29));

       ts.add(new Person("lisi2",67));

       ts.add(new Person("lisi8",28));

       ts.add(new Person("lisi0",20));

       System.out.println(ts);

       }

}

//自定义一个比较器。

classCompareByName implements Comparator{

      public int compare(Object o1,Object o2){

       Person p1 = (Person)o1;

       Person p2 = (Person)o2;

       int num =p1.getName().compareTo(p2.getName());

       returnnum==0?p1.getAge()-p2.getAge():num;

       }

}

class Personimplements Comparable{

       private String name;

       private int age;

       Person(String name,int age){

              this.name = name;

              this.age = age;

       }

     //人的自然排序是按照年龄排序

      public int compareTo(Object obj){

       Person p = (Person)obj;

       int num = newInteger(this.age).compareTo(new Integer(p.age));

       returnnum==0?this.name.compareTo(p.name):num;

       }

       public String getName(){

              return name;

       }

       public int getAge(){

              return age;

       }

       public String toString(){

              return name+"::"+age;

       }

}

 

------- android培训java培训、期待与您交流! ----------  详细请查看:http://edu.csdn.net/heima/