java集合学习总结

 

 

一、为什么会出现集合类?

      面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,需要对对象进行存储,而集合就是最常用的一种方式

二、集合类的特点:

        集合只用于存储对象,

        集合的长度是可变的,

        集合中可以存储不同类型的对象。

三、集合框架结构图

 

四、集合中的数据特点

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


五、详细分析

上图太过复杂,来个简化版:


集合的框架体系是个很明显的继承体系,因此在学习时,我们可以自上往下学习:先学共性,再学特性
1>、Collection接口
   Collection是集合框架的父接口,Set List由它派生,因此我们可以通过它来发现集合类的共性方法:
    基本操作 
    1、增加元素
add(Object obj); 
addAll(Collection c);
    2、删除元素
remove(Object obj); 
removeAll(Collection c);
    3、判断    
        retainAll(Collection c); //求交集

   4、获取:

   int size();

   Iterator iterator();//取出元素的方式:迭代器。

  迭代器:专门用于取出集合中元素的方式。

  访问/遍历集合元素的办法是使用Iterator接口(迭代器用于取代Enumeration)
2>、集set

  元素是无序的,集合中没有重复元素
  有三种特定类型的集可用
  1、 HashSet-底层数据结构是哈希表

****      HashSet是如何保证元素的唯一性呢?             
      是通过元素的两个方法,hashCode和equels来完成的,如果元素的hashCode值相同,才会去判断其equals是否为true 如果元素的hashCode值不同,就不会调用其equals

代码示例:

 

class HashSetTest
{
  public static void main(String[] args) 
  {
    HashSet hs = new HashSet();   
    hs.add(new Person("a1",11));
    hs.add(new Person("a2",12));
    hs.add(new Person("a3",13));
    hs.add(new Person("a4",14));
    hs.add(new Person("a1",11));

    Iterator it = hs.iterator();
    while(it.hasNext())
    {
      Person p = (Person)it.next();
      sop(p.getName()+"::"+p.getAge());
    }
  }

  public static void sop(Object obj)
  {
    System.out.println(obj);
  }
}

 

Person类的代码:

class Person
{
   private String name;
   private int age;

   public Person(String name,int age)
   {
    this.name = name;
    this.age = age;
   }
 
   public String getName()
   {
     return name;
   }
   public int getAge()
   {
     return age;
   }
/*
由于HashSet在进行元素判断时会调用元素的equals方法,因此需要对
其进行重写,不然会调用其超类Object的equals方法
*/
  public boolean equals(Object obj)
  {
    if(!(obj instanceof Person))
    return false;

    Person p = (Person)obj;
  //输出语句用于显示怎么调用的equals方法

    System.out.println(this.name+"......"+p.name);


    return this.name.equals(p.name) && this.age == p.age;
  }
  //
  public int hashCode()
  {
    System.out.println(this.name+"....hashCode");
    return name.hashCode()+age*39;
  }
 
}

 

  2、LinkedHashSet-对集迭代时,按增加顺序返回元素

 3、TreeSet-基于二叉树树的数据结构
     最大特点:可以对集合中的元素排序

*****对元素进行排序的方式:

第一种方式是:
  元素必须实现comparable接口,覆写compareTo方法,这种方式也称为元素的
自然排序,或者叫做默认排序。


 第二种方式:
  当元素不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合
自身具备比较性。也就是在集合初始化时就让集合具备比较性:定义一个比较器
并将比较器作为参数传递给TreeSet的构造函数,定义一个类继承自Comparator接口,覆写
其compare方法


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

 

  3>、清单List

--元素是有序的,集合中可以存入重复元素,可以通过索引来操作元素
  有两个特定版本
   1
、ArrayList(数组表)-
       类似于Vector,都用于缩放数组维护集合。区别:
      一.同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的
      二.数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半
   2、LinkedList(链表)-

        是双向链表,每个节点都有两个指针指向上一节点和下一节点。

        模仿队列FIFO,用addList()加入元素 removeFirst()删除元素

        模仿堆栈FILO,用addFirst()/removeLast()

 

    3、ListIterator 列表迭代器

      提供双向遍历next() previous(),可删除、替换、增加元素

示例代码:

import java.util.*;
//实现队列功能:FIFO
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();
  }
}

class LinkedListTest 
{
  public static void main(String[] args) 
  {
    DuiLie dl = new DuiLie();
    dl.myAdd("java01");
    dl.myAdd("java02");
    dl.myAdd("java03");
    dl.myAdd("java04");

    while(!dl.isNull())
    {
      System.out.println(dl.myGet());
    }

  }
}
4>、映射表Map
  1、--用于关键字/数值对
       处理Map的三种集合
               关键字集KeySet()                数值集value()                映射集enrySet()
  2、常用子类对象
    |---HashMap:看到Hash我们要想到的是哈希表,就要想到元素的唯一性,
            元素要覆盖hashCode()和equals()
    |---TreeMap:可以对Map集合中的元素进行排序,
                排序两种方式:
          1>、元素自身具备比较性,即元素实现comparable接口的compareTo方法
          2>、集合具备比较性,即自定义比较器,并在集合初始化时作为参数传递给集合的构造函数 

   3、Map集合的常用方法:

    1.添加:

      value put(key,value);   //返回前一个和key关联的值,如果没有返回null

    2.删除;

      value remove(key);   //根据指定的key删除这个键值对,

      void clear();  //清空map集合。

    3.判断:

      boolean containsKey(key);

      boolean containsValue(value);

      boolean siEmpty();

    4.获取:

      value get(key);    //通过键拿值,如果没有该键,返回null。可以通过是否返回null,判断是否包含指定键。

      int size();    //获取键值对的个数。

一个完整的实例代码:

/*
需求:
1,每个学生都有对应的归属地
2,学生属性:姓名,年龄
3,姓名和年龄相同视为同一个学生
保证学生的唯一性

分析:
1,描述学生
2,定义map容器,将学生作为键,地址作为值存入
3,获取map集合中的元素
*/
class Student implements Comparable<Student>
{
  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;   }
  
public String toString()   {     return name+"::"+age;   }
  
public int hashCode()   {     return name.hashCode()+age*34;   }
  
public boolean equals(Object obj)   {     if (!(obj instanceof Student))     //return false;       throw new ClassCastException("类型转换错误!!!");     Student stu = (Student)obj;     return this.name.equals(stu.name) && this.age == stu.age;   }
  
public int compareTo(Student s)   {     int num = new Integer(this.age).compareTo(new Integer(s.age));     if (num==0)       return this.name.compareTo(s.name);     return num;   } }

class HashMapTest 
{
  public static void main(String[] args) 
  {
    HashMap<Student,String> hm = new HashMap<Student,String>();
    hm.put(
new Student("lisi1",21),"beijing");     hm.put(new Student("lisi2",22),"tianjin");     hm.put(new Student("lisi3",23),"wuhan");     hm.put(new Student("lisi4",24),"nanjing");
    
//第一种取出方式:keySet     Iterator<Student> it = hm.keySet().iterator();
    
while(it.hasNext())     {       Student stu = it.next();       String addr = hm.get(stu);       System.out.println(stu+"..."+addr);     }     //第二种方式:entrySet     Set<Map.Entry<Student,String>> entrySet = hm.entrySet();
    Iterator
<Map.Entry<Student,String>> iter = entrySet.iterator();
    
while (iter.hasNext())     {       Map.Entry<Student,String> me = iter.next();       Student stu = me.getKey();       String addr = me.getValue();       System.out.println(stu+"........"+addr);     }   } }

六、集合使用的一些技巧:

  1>、选择哪种集合: 

     1、 需要唯一吗?

       需要:Set

    2、 需要指定顺序吗?

      需要:TreeSet

      不需要:HashSet

    3、想要一个和存储一致的顺序(有序):

      需要:LinkedHashSet

      不需要:List

    4、需要频繁增删吗?

      需要:LinkedList

      不需要:ArrayList

  2>、如何记住每一个容器的结构和所属体系。

    看名字:后缀名就是该集合所属的体系。

    List有角标有序,可重复。Set元素唯一

    前缀名就是该集合的数据结构。

  3>、基本素质:

    看到Array就想到数组,就要想到查询快,有角标。

    看到Linked就要想到链表就要想到增删快,add  get  remove+first last的方法。

    看到Hash就要想到哈希表,就要想到唯一性,元素需要想到覆盖hashCode方法和equals方法。

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

 

   

 

 

 


posted on 2013-01-18 17:12  Xiaobin.Wang  阅读(293)  评论(0)    收藏  举报

导航