Java集合<上>

集合类

定义:为了方便对多个对象的操作,就对对象进行存储,集合就是其中的一种方式

集合和数组的不同之处:

1,数组是固定长度的,集合是可变长度

2,数组可以储存基本数据类型和引用型数据类型,集合只能存储引用数据类型

3,数据存储的元素必然是统一个数据类型,集合存储的对象是不同数据类型

数据结构:

数据结构就是容器中存储数据的方式,对于集合容器,有很多种。因为每一个容器的自身特点不同,其实原理在于每个容器的内部数据结构不同。

集合容器在不断向上抽取过程中。出现了集合体系。

集合框架结构图:



------------------------------------------------------------------------------------------------------------------

Collection接口

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

|--Set:无序(存入和取出顺序有可能不一致),不可以存储重复元素。必须保证元素唯一性

提供的方法:

1,添加:

add(E a) 确保此collection包含指定的元素

 addAll(Collection<? extends E>c)将指定collection中的所有元素都添加到此collection中。

2,删除

clear()将集合中的元素全删除,即清空集合

remove(Object o)从此collection中移除指定元素的单个实例,如果存在的话,注意:删除成功,集合的长度会改变。

removeAll(Collection<?>c)移除此collection中那些也包含在指定collection中的所有元素 

3,判断

boolean  isEmpty()如果此collection不包含元素,则返回true

4,获取

boolean contains(obj) :集合中是否包含指定元素 。

boolean containsAll(Collection) :集合中是否包含指定的多个元素。

int size() 返回此collection中的元素数

5,取交集

boolean retainAll(Collection<?>c)仅保留此collection中那些也包含在指定collection的元素。集合和数组一样,里面存的都是地址。

6,获取集合中所有元素:

Iterator iterator()返回在此collection的元素上进行迭代的迭代器

7,将集合变成数组:

toArray()返回包含此collection中所有元素的数组

toArray(T[]a)返回包含此collection中所有元素的数组,返回数组的运行时类型与指定数组的运行时类型相同。

hashCode()返回此collection的哈希码值。

注意:集合里存储的是应用地址

--------------------------------------------------------------------------------------------------------------------------

Iterator接口

迭代器:

其实就是集合的取出元素的方式,就把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内部的元素,那么取出方式就被定义成了内部类,而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容,判断和取出,那么可以将这些共性抽取,那么这个内部类都符合一个规则,该规则是Iterator。

方法:

1,boolean hasNext():如果仍有元素可以迭代,则返回true.

2,next():返回迭代的下一个元素

3,void remove():从迭代器指向的collection中移除迭代器返回的最后一个元素

Iterator it = coll.iterator();//获取容器中的迭代器对象,至于这个对象是是什么不重要。这对象肯定符合一个规则Iterator接口。

[java]  view plain copy
  1. import java.util.*;    
  2. public class collectionDemo {    
  3.     public static void main(String[] args) {    
  4.         method();    
  5.     }    
  6.     public static void method_get()    
  7.     {    
  8.         //创建一个集合容器,使用collection接口的子类。ArrayList    
  9.         ArrayList a1=new ArrayList();    
  10.         a1.add("java01");    
  11.         a1.add("java03");    
  12.         /**Iterator it=a1.iterator();//获取迭代器,用于取出集合中的元素  
  13.         while(it.hasNext());  
  14.         {   
  15.             sop(it.next());  
  16.         }//写for更优些。it是局部变量,用完就释放。而while中就没释放。  
  17.         */    
  18.         for(Iterator it=a1.iterator();it.hasNext();)    
  19.         {    
  20.             sop(it.next());    
  21.         }    
  22.     }    
  23.     public static void method()    
  24.     {    
  25.            //创建一个集合容器,使用collection接口的子类。ArrayList    
  26.                 ArrayList a1=new ArrayList();    
  27.                 //1.添加元素    
  28.                 a1.add("java01");//add(Object obj)    
  29.                 a1.add("java03");    
  30.                 ArrayList a2=new ArrayList();    
  31.                 //1.添加元素    
  32.                 a2.add("java01");//add(Object obj)    
  33.                 a2.add("java02");    
  34.                 a1.retainAll(a2);//取交集,a1中只会保留和a2中相同的元素    
  35.                 a1.removeAll(a2);//移除与a2中相同的元素。    
  36.                 sop("a1:"+a1);    
  37.                 sop("a2:"+a2);    
  38.     }    
  39.     public static void base_method()    
  40.     { //创建一个集合容器,使用collection接口的子类。ArrayList    
  41.         ArrayList a1=new ArrayList();    
  42.         //1.添加元素    
  43.         a1.add("java01");//add(Object obj)    
  44.         a1.add("java02");    
  45.         //打印集合    
  46.         sop(a1);    
  47.         //2.获取个数,集合长度    
  48.         sop("size:"+a1.size());    
  49.         //3.删除元素    
  50.         a1.remove("java02");    
  51.         a1.clear();//清空集合    
  52.         //打印改变后的集合    
  53.         sop(a1);    
  54.         //4判断元素    
  55.         sop("java03是否存在"+a1.contains("java03"));    
  56.         sop("集合是否为空?"+a1.isEmpty());    
  57.     }    
  58.     public static void sop(Object obj)    
  59.     {    
  60.         System.out.println(obj);    
  61.     }    
  62. }    
_________________________________________________________________________________________________

List接口

|---list:元素是有序的,元素可以重复,因为该集合体系有索引
                 | --ArrayList:底层的数据结构使用的是数组结构,特点:查询速度快。但是增删稍慢。线程不同步。50%延长,是 1.2版线程不同步。它默认的长度10元素,超出时,以50%延长                                                                        
                 |--LinkedList:底层使用的是链表数据结构。特点:增删速度快,查询稍慢
                 |--Vector:底层是数组数据结构。1.0版,是同步的。被arrayList替代了。长度为10,长度百分百延长,
|---set:元素是无序(存入和取出的顺序不一定一致)元素不可以重复。
                |----hashSet :底层数据结构是哈希表。线程是非同步的
方法:
1,添加:
    add(index,element) :在指定的索引位插入元素。
    addAll(index,collection) :在指定的索引位插入一堆元素。
2,删除:
    remove(index) :删除指定索引位的元素。 返回被删的元素。
3,获取:
    Object get(index) :通过索引获取指定元素。
    int indexOf(obj) :获取指定元素第一次出现的索引位,如果该元素不存在返回-1;所以,通过-1,可以判断一个元素是否存在。
    int lastIndexOf(Object o) :反向索引指定元素的位置。
    List subList(start,end) :获取子列表。
4,修改:
    Object set(index,element) :对指定索引位进行元素的修改。
5,获取所有元素:
    ListIterator listIterator():list集合特有的迭代器。
在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。所以,在迭代器时,只能用迭代器的放过操作元素,可是Iterator方法是有限的只能对元素进行判断,取出,删除的操作
如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator,该接口只能通过List集合的listIterator方法获取。
方法:
boolean hasPrevious():如果以逆向遍历列表,列表迭代器有多个元素,则返回true。
int nextIndex():返回对next的后续调用所d返回元素的索引。
previous():返回列表中的前一个元素。
int previousIndex():返回对previous的后续调用返回元素的索引。
void remove():从列表中移除由next或previous返回的最后一个元素(可选操作)。
void set(E e):用指定元素替换next或previous返回的最后一个元素(可选操作)。
List集合支持对元素的增、删、改、查。
list特有方法,凡是可以操作角标的方法都是该体系特有的方法
在进行list列表元素迭代的时候,如果想要在迭代过程中,想要对元素进行操作的时候,比如满足条件添加新元素。会发生.ConcurrentModificationException并发修改异常。
导致的原因是:集合引用和迭代器引用在同时操作元素,通过集合获取到对应的迭代器后,在迭代中,进行集合引用的元素添加,迭代器并不知道,所以会出现异常情况。
ListIterator是List集合特有的迭代器。 ListIterator it = list.listIterator;//取代Iterator it = list.iterator;

注意:对于list集合,底层判断元素是否相同,其实用的是元素自身的equals方法完成的。所以建议元素都要复写equals方法,建立元素对象自己的比较相同的条件依据
hashSet是如何保证元素唯一性的呢?
 
答:是通过元素的两个方法,hashCode和equals完成,如果元素的hashcode值相同,才会判断equals是否为true。如果元素的hashcode值不同,不会调用equals
注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。
TreeSet:可以对set集合中的元素进行排序。Set集合的功能和collection是一致的。
list特有方法,凡是可以操作角标的方法都是该体系特有的方法
[java]  view plain copy
  1. import java.util.*;    
  2. public class listDemo {    
  3.     public static void method()    
  4.     {    
  5.          ArrayList a1=new ArrayList();    
  6.             //添加元素    
  7.             a1.add("java01");    
  8.             a1.add("java02");    
  9.             sop("原集合是:"+a1);    
  10.             //在指定位置添加元素,相当于插入,    
  11.             a1.add(1"java09");    
  12.             //删除指定位置元素。按角标删除    
  13.             a1.remove(2);    
  14.             //修改元素。按角标修改    
  15.             a1.set(2"java007");    
  16.             //通过角标获取元素    
  17.            sop("get(1)"+ a1.get(1));    
  18.             sop(a1);    
  19.             //获取所有元素    
  20.             for(int x=0;x<a1.size();x++)    
  21.             {    
  22.                 System.out.println("a1("+x+")="+a1.get(x));    
  23.             }    
  24.             Iterator it=a1.iterator();    
  25.             while(it.hasNext())    
  26.             {    
  27.               sop("next:"+it.next());       
  28.             }    
  29.             //通过indexof获取对象的位置    
  30.             sop("index="+a1.indexOf("java02"));    
  31.             List sub=a1.subList(13);    
  32.             sop("sub="+sub);    
  33.     }    
  34.     public static void main(String[] args) {    
  35.                         //演示列表迭代器     
  36.          ArrayList a1=new ArrayList();    
  37.             //添加元素    
  38.             a1.add("java01");    
  39.             a1.add("java02");    
  40.             sop("原集合是:"+a1);    
  41.             ListIterator li=a1.listIterator();    
  42.             while(li.hasNext())    
  43.             {    
  44.                 Object obj=li.next();    
  45.                 if(obj.equals("java02"))    
  46.                     li.add("java009");//添加    
  47.                   li.set("java006");//修改    
  48.             }    
  49.             while(li.hasPrevious())//逆向遍历列表,    
  50.             {    
  51.                 sop("pre:"+li.previous());//    
  52.             }    
  53.             sop("hasNext"+li.hasNext());//正向遍历    
  54.             sop("hasPrevious():"+li.hasPrevious());//逆向遍历。    
  55.             sop(a1);    
  56.          /**   //在迭代过程中,准备添加或删除元素  
  57.             Iterator it=a1.iterator();//这个迭代器不能添加  
  58.             while(it.hasNext())  
  59.             {  
  60.              Object obj=it.next();  
  61.              if(obj.equals("java02"))  
  62.                 // a1.add("java003");  
  63.                  it.remove();//将Java02的引用从集合中删除了。  
  64.                 sop("obj="+obj);  
  65.             }  
  66.             */    
  67.     }    
  68.     public static void sop(Object obj)    
  69.     {    
  70.         System.out.println(obj);    
  71.     }    
  72. }    
----------------------------------------------------------------------------------------------------------------------------------------------------------

LinkedList

方法新特性:
addFirst();
addLast();
在jdk1.6以后。
offerFirst();相当于add
offerLast();
getFirst():获取链表中的第一个元素。如果链表为空,抛出NoSuchElementException;
getLast();获取元素但不删除元素如果集合中没有元素,会出现NosuchElementException
在jdk1.6以后。
peekFirst();获取链表中的第一个元素。如果链表为空,返回null。
peekLast();相当于get
removeFirst():获取链表中的第一个元素,但是会删除链表中的第一个元素。如果链表为空,抛出NoSuchElementException
removeLast();获取元素并删除元素,如果集合中没有元素,会出现NosuchElementException
在jdk1.6以后。
pollFirst();//相当于remove
获取链表中的第一个元素,但是会删除链表中的第一个元素。如果链表为空,返回null。
pollLast();获取元素并删除元素,如果集合中没有元素,会返回null
[java]  view plain copy
  1. import java.util.*;    
  2. public class LinkedListDemo {    
  3.     public static void main(String[] args) {    
  4.         LinkedList link=new LinkedList();    
  5.         link.addFirst("java01");    
  6.         link.addFirst("java011");    
  7.         link.addFirst("java01111");//头插法    
  8.         link.addFirst("java02");    
  9.         link.addLast("java0121");//尾插法    
  10.         link.addLast("java011211");    
  11.         sop(link);    
  12.         sop(link.getFirst());//获取头    
  13.         sop(link.getLast());//获取尾    
  14.         sop("size="+link.size());//获取长度。    
  15.         sop(link.removeFirst());    
  16.         while(!link.isEmpty())    
  17.         {    
  18.             sop(link.removeFirst());//正着取出    
  19.             sop(link.removeLast());//反着取出    
  20.         }    
  21.     }    
  22.     public static void sop(Object obj)    
  23.     {    
  24.         System.out.print(obj);    
  25.     }    
  26. }    

练习范例:
去除集合重复元素
[java]  view plain copy
  1. import java.util.*;    
  2. public class ArrayListTest {    
  3.     public static void main(String[] args) {    
  4.      ArrayList al=new ArrayList();    
  5.      al.add("java01");    
  6.      al.add("java02");    
  7.      al.add("java03");    
  8.      al.add("java04");    
  9.      al.add("java01");    
  10.      al.add("java02");    
  11.      /**  
  12.       * 在迭代时循环中next只能调用一次,就要hasNext判断一次。  
  13.      Iterator it=al.iterator();  
  14.      while(it.hasNext())  
  15.      {  
  16.          sop(it.next()+"....."+it.next());  
  17.      }  
  18.       */    
  19.      sop(al);    
  20.      al=singleElement(al);    
  21.      sop(al);    
  22.     }    
  23.     public static ArrayList singleElement(ArrayList al)    
  24.     {   //定义一个临时容器    
  25.         ArrayList newal=new ArrayList();    
  26.             Iterator it=al.iterator();    
  27.             while(it.hasNext())    
  28.             {    
  29.                 Object obj=it.next();    
  30.                 if(!newal.contains(obj))    
  31.                 {    
  32.                     newal.add(obj);    
  33.                 }    
  34.             }    
  35.             return newal;    
  36.     }    
  37.     public static void sop(Object obj)    
  38.     {     
  39.         System.out.println(obj);    
  40.     }    
  41. }    
_________________________________________________________________________________________________________

Set接口

  |--HashSet:底层数据结构是哈希表,线程是不同步的。无序,高效;
      HashSet集合保证元素唯一性:通过元素的hashCode方法,和equals方法完成的。
      当元素的hashCode值相同时,才继续判断元素的equals是否为true。
      如果为true,那么视为相同元素,不存。如果为false,那么存储。
      如果hashCode值不同,那么不判断equals,从而提高对象比较的速度。
      |--LinkedHashSet:有序,hashset的子类。
  |--TreeSet:对Set集合中的元素的进行指定顺序的排序。不同步。TreeSet底层的数据结构就是二叉树。
判断元素是否存在:
对于ArrayList集合,判断元素是否存在,或者删元素底层依据都是equals方法。
对于HashSet集合,判断元素是否存在,或者删除元素,底层依据的是hashCode方法和equals方法。
TreeSet:
  用于对Set集合进行元素的指定顺序排序,排序需要依据元素自身具备的比较性。
   如果元素不具备比较性,在运行时会发生ClassCastException异常。
  所以需要元素实现Comparable接口,强制让元素具备比较性,复写compareTo方法。
  依据compareTo方法的返回值,确定元素在TreeSet数据结构中的位置。
  TreeSet方法保证元素唯一性的方式:就是参考比较方法的结果是否为0,如果return 0,视为两个对象重复,不存。

TreeSet集合排序有两种方式, Comparable和Comparator区别
1:让元素自身具备比较性,需要元素对象实现Comparable接口,覆盖compareTo方法。
2:让集合自身具备比较性,需要定义一个实现了Comparator接口的比较器,并覆盖compare方法,并将该类对象作为实际参数传递给TreeSet集合的构造函数。
范例:往hashset集合中存入自定对象,姓名和年龄相同为同一个人,重复元素
[java]  view plain copy
  1. import java.util.*;    
  2. public class HashSetTest {    
  3.     public static void main(String[] args) {    
  4.         HashSet hs=new HashSet();    
  5.         hs.add(new Person1("a1",11));    
  6.         hs.add(new Person1("a2",12));    
  7.         hs.add(new Person1("a3",13));    
  8.         hs.add(new Person1("a2",12));    
  9.         hs.add(new Person1("a3",13));    
  10.         hs.add(new Person1("a4",14));    
  11.         //判断是否存在    
  12.         //hs.contains(new Person1("a1",11));//先判断的是hash值。    
  13.         //hs.remove(new Person1("a2”,13));//    
  14.         Iterator it=hs.iterator();    
  15.         while(it.hasNext())    
  16.         {    
  17.             Person1 p=(Person1)it.next();    
  18.             sop(p.getAge()+"::"+p.getName());    
  19.         }    
  20.     }    
  21.    public static void sop(Object obj)    
  22.    {    
  23.        System.out.println(obj);    
  24.    }    
  25. }    
  26. class Person1    
  27. {   private String name;    
  28.     private int age;    
  29.     Person1(String name,int age)    
  30.     {    
  31.         this.name=name;    
  32.         this.age=age;    
  33.     }    
  34.     public int hashCode()    
  35.     {    
  36.         //return 60;    
  37.         return name.hashCode()+age*39;    
  38.     }    
  39.     public boolean equals(Object obj)    
  40.     {      
  41.         if(!(obj instanceof Person1))    
  42.             return false;    
  43.         Person1 p=(Person1)obj;    
  44.         System.out.println(this.name+",,,,,,,,,,,,,,"+p.name);    
  45.         return this.name.equals(p.name)&&this.age==p.age;    
  46.     }    
  47.     public String getName()    
  48.     {    
  49.         return name;    
  50.     }    
  51.     public int getAge()    
  52.     {    
  53.         return age;    
  54.     }       
  55. }    
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Set 接口:

无序,不可以重复元素。
     |---HashSet :数据结构是哈希表,线程是非同步的
                 保证元素唯一性的原理:判断元素的hashCode值是否相同
                 如果相同,还会继续判断元素的equals方法,是否为true
     |---TreeSet:可以对Set集合中的元素进行排序。
                底层数据结构是二叉树
                保证元素唯一性的依据
                compareTo方法return 0;
        TreeSet排序的第一种方式,让元素自身具备比较性,
         元素需要实现Comparable接口,覆盖compareTo方法。
        这种方式也称为元素的自然顺序,或叫默认顺序。
        TreeSet排序的第二种方式,当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。
        在集合初始化时,就有了比较方式。

comparable接口强行对实现它的每个类的对象进行整体排序。
记住,排序时,当主要条件相同时,一定要判断一下次要条件 。
可以对set集合中的元素进行排序,底层数据结构是二叉树,保证元素唯一性的依据
compareTo方法return 0;
TreeSet排序的第一种方式:让元素自身具备比较性,元素需要实现comparable接口,覆盖compareTo方法, 这种方式也称为元素的自然顺序,或叫默认顺序。
范例:
往Treeset集合中存储自定义对象,学生,想按照学生的年龄进行排序
[java]  view plain copy
  1. import java.util.Iterator;    
  2. import java.util.TreeSet;    
  3. public class TreeSetDemo {    
  4.     public static void main(String[] args) {    
  5.         TreeSet ts=new TreeSet();    
  6.         ts.add(new Student("lisi09",33));    
  7.         ts.add(new Student("lisi02",34));    
  8.         ts.add(new Student("lisi23",23));    
  9.         ts.add(new Student("lisi01",23));    
  10.         ts.add(new Student("lisi23",23));    
  11.         ts.add(new Student("lisi01",3));    
  12.         Iterator it=ts.iterator();    
  13.         while(it.hasNext())    
  14.         {   Student stu=(Student)it.next();    
  15.             System.out.println(stu.getName()+"...."+stu.getAge());    
  16.         }    
  17.     }    
  18. }    
  19. class Student implements Comparable //该接口强制让学生具有比较性    
  20. {    
  21.     private String name;    
  22.     private int age;    
  23.     Student(String name,int age)    
  24.     {    
  25.         this.name=name;    
  26.         this.age=age;    
  27.     }    
  28.   public String getName()    
  29.   {    
  30.       return name;    
  31.   }    
  32.   public int getAge()    
  33.   {    
  34.       return age;    
  35.   }    
  36.   public int compareTo(Object obj)    
  37.     {    return 1;//输入的字符串的比较正向,变-1反向    
  38.         /**if(!(obj instanceof Student))  
  39.            throw new RuntimeException("不是学生对象");  
  40.            Student s=(Student)obj;  
  41.            System.out.println(this.name+"ddddd"+s.name);  
  42.            if(this.age>s.age)  
  43.                return 1;  
  44.            if(this.age==s.age)  
  45.            {  
  46.                return this.name.compareTo(s.name);  
  47.            }  
  48.            return -1;  
  49.            */    
  50.       }    
  51. }    
范例2:按照字符串长度排序
提示:字符串本身具备比较性,但是它的比较方式不是所需要的,这时就只能使用比较器。
[java]  view plain copy
  1. import java.util.*;    
  2. public class TreesetTest {    
  3.     public static void main(String[] args) {        
  4.     TreeSet ts=new TreeSet(new stringlencomparator());  //传入比较器  
  5.      ts.add("aa");    
  6.      ts.add("cess");    
  7.      ts.add("agweg");    
  8.      ts.add("s");    
  9.      Iterator it=ts.iterator();    
  10.      while(it.hasNext())    
  11.      {    
  12.          System.out.println(it.next());    
  13.      }    
  14.     }    
  15. }    
  16. class  stringlencomparator implements Comparator    
  17. {    
  18.     public int compare(Object o1,Object o2)  //比较器  
  19.     {    
  20.         String s1=(String)o1;    
  21.         String s2=(String)o2;    
  22.         /**  if(s1.length()>s2.length())  
  23.            return 1;  
  24.        if(s1.length()==s2.length())  
  25.            return 0;  
  26.        return -1;  
  27.        */    
  28.         int num=new Integer(s1.length()).compareTo(new Integer(s2.length())); //排序   
  29.         if(num==0)    
  30.             return s1.compareTo(s2);    
  31.         return num;    
  32.     }    
  33.     }    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值