码迷,mamicode.com
首页 > 编程语言 > 详细

java容器---集合总结

时间:2014-09-01 00:18:12      阅读:367      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   os   io   使用   java   strong   ar   

思考为什么要引入容器这个概念?

   Java有多种方式保存对象(应该是对象的引用),例如使用数组时保存一组对象中的最有效的方式,如果你想保存一组基本类型的数据,也推荐使用这种方式,但大家知道数组是具有固定尺寸的,你必须事先知道你要需要多少个对象。但是在一般的情况中,你在写程序中并不知道将需要多少个对象,或者是否需要更加复杂的方式来存储对象,因此数组尺寸固定很不爽!

   为了解决上述问题,引入了容器的概念。容器提供了完善的方法来保存对象,你可以使用这些工具来解决数量惊人的问题。Java容器类可以自动调整自己的尺寸,因此与数组不同,你可以将任意数量的对象放到容器中,并不担心容器设置为多大。

bubuko.com,布布扣

集合特点:
1,用于存储对象的容器。
2,集合的长度是可变的。
3,集合中不可以存储基本数据类型值。

java容器类库用途是保存对象。分为2类:

 1. Collection

      一个独立元素的序列,这些元素都服从一条或多条规则。List必须按照插入的顺序保存元素,Set不能有重复元素。Queue按照排队规则来确定对象产生的顺序(通常与插入的顺序相同)。

 2. Map

      一组成对的键值对对象,允许使用键来查找值,将数字和对象关联到一起。映射表允许我们使用另一个对象来查找某个对象,也被称为关联数组或字典。Map很强大

List类型

List接口在Collection的基础上添加了大量的方法,使得可以在List中间插入和移除元素。

   1 ArrayList和 LinkedList

  都按照被插入的顺序保存元素,区别在于执行某些操作时的性能。且LinkedList包含的操作也多于ArrayList.

(1)ArrayList  :优势随机访问元素比较快,有连续的数组空间,但是在List的中间插入和移除元素时较慢,需要大量的移动内部的元素。

   你可以把ArrayList  当做“可以自动扩充自身的数组”来看待,使用ArrayList也相当简单:创建一个实例,用add()插入对象;然后用get()访问这些对象,此时需要索引,就像数组一样,但是不需要方括号。ArrayList还有一个size()方法,使你知道有多少个元素添加进来,从而不会不小心因索引越界而引发错误。

(2)LinkedList:在LinkedList中间插入删除较快,提供优化的顺序访问。随机访问时较慢,特性集较ArrayList  大。各种Queue以及栈的行为,由LinkedList提供支持。

Set类型

    1.HashSet TreeSet LinkedHashSet 

    输出显示在Set中,每个相同的项只保存一次,但存储的方式不同

    (1)  Hashset存储方式复杂,但保证了最快的获取速度

   (2)TreeSet按照升序保存对象

   (3)LinkedHashSet按照添加的顺序保存对象

 

Map

 

    可以使用键来查找对象,类似于数组下标。Map.put(key,value)插入数据,Map.get(key)查找数据。键要求唯一。存储方式不是顺序存储,速度快。不必指定Map的尺寸,因为它自己会自动的调整。

 

   (1)HashMap使用最快的查找技术,存储无顺序。

 

   (2)TreeMap按照比较结果升序保存。

 

   (3)LinkedHashMap按照插入顺序保存键,同时保留HashMap的查询速度

迭代器(也是一种设计模式)

   容器缺点:使用容器,必须对容器的确切类型进行编程,但若像更换或扩展至其他容器,必须重写代码。迭代器可以解决这个问题,实现代码的重用。它是一个对象,它的工作是遍历并选择序列中的对象,而客户端程序员不必知道或关心该序列底层的结构。它是轻量级对象,创建的代价小。

因此经常对迭代器有些奇怪的限制:

1)使用方法Iterator()要求容器返回一个IteratorIterator将准备好返回序列中的第一个元素。

2)使用next()获得序列的下一个元素。

3)使用hasNext()检查序列中是否还有元素。

4)使用remove()将迭代器新近返回的元素删除。

    迭代器能够将遍历序列的操作与序列底层的结构分离,它统一了对容器的访问方式,这是它的威力所在。

框架的顶层Collection接口:

Collection的常见方法:

1,添加。
    boolean add(Object obj):
    boolean addAll(Collection coll):

2,删除。
    boolean remove(object obj):
    boolean removeAll(Collection coll);
    void clear();
3,判断:
    boolean contains(object obj):
    boolean containsAll(Colllection coll);
    boolean isEmpty():判断集合中是否有元素。
4,获取:
    int size():
    Iterator iterator():取出元素的方式:迭代器。
    该对象必须依赖于具体容器,因为每一个容器的数据结构都不同。
    所以该迭代器对象是在容器中进行内部实现的。
    对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可,
    也就是iterator方法。
    Iterator接口就是对所有的Collection容器进行元素取出的公共接口。
5,其他:
    boolean retainAll(Collection coll);取交集。
    Object[] toArray():将集合转成数组。

package cn.itcast.p3.collection.demo;

import java.util.ArrayList;
import java.util.Collection;

public class CollectionDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        /*Collection coll = new ArrayList();
        show(coll);
    */
        Collection c1 = new ArrayList();
        Collection c2 = new ArrayList();
        show(c1,c2);
        
    }
    
    public static void show(Collection c1,Collection c2){
        
        //给c1添加元素。
        c1.add("abc1");
        c1.add("abc2");
        c1.add("abc3");
        c1.add("abc4");
        
        //给c2添加元素。
        c2.add("abc2");
        c2.add("abc5");
        c2.add("abc6");
        
        System.out.println("c1:"+c1);//c1:[abc1, abc2, abc3, abc4]
        System.out.println("c2:"+c2);//c2:[abc2, abc5, abc6]
        
        
        //将c2中的元素添加到c1集合中,添加一堆
        c1.addAll(c2);
        System.out.println(c1);//[abc1, abc2, abc3, abc4, abc2, abc5, abc6]
        
        //演示removeAll
        //将两个集合中的相同元素从调用removeAll的集合中删除,从c1中删除c1和c2相同的元素
    /*    boolean b = c1.removeAll(c2);
        System.out.println("removeAll:"+b);
        System.out.println("c1"+c1);//c1[abc1, abc3, abc4]
*/        
        //演示containsAll,c1集合中是否包含C2中的所有元素,包含返回true
        boolean b1 = c1.containsAll(c2);
        System.out.println("containsAll:"+b1);
//演示retainAll 取交集,保留和指定的集合相同的元素,而删除不同的元素。和removeAll功能相反 。
        //c2:[abc2, abc5, abc6],
        //addAll后的C1:[abc1, abc2, abc3, abc4, abc2, abc5, abc6]
// boolean b = c1.retainAll(c2); // System.out.println("retainAll:"+b); // System.out.println("c1:"+c1);//c1:[abc2, abc2, abc5, abc6] } /** * 测试集合 Collection集合中的方法 * @param coll */ public static void show(Collection coll){ //1,添加元素。add. coll.add("abc1"); coll.add("abc2"); coll.add("abc3"); System.out.println(coll); //2,删除元素。remove if(coll.contains("abc2")){ coll.remove("abc2");//会改变集合的长度 } //清空集合 //coll.clear();//清空集合中的元素,但是集合还在,集合为[]空 System.out.println(coll.contains("abc3")); System.out.println(coll); } }

Collection集合的遍历:使用Iterator

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class IteratorDemo {

    /**
     * java.util.NoSuchElementException
     */
    public static void main(String[] args) {

        Collection coll = new ArrayList();
        coll.add("abc1");
        coll.add("abc2");
        coll.add("abc3");
        coll.add("abc4");
        System.out.println(coll);//[abc1, abc2, abc3, abc4]
        //使用了Collection中的iterator()方法。 调用集合中的迭代器方法,是为了获取集合中的迭代器对象。
        Iterator it = coll.iterator();        
        while(it.hasNext()){
            System.out.println(it.next());
        }
        
    /*    for(Iterator it = coll.iterator(); it.hasNext(); ){
            System.out.println(it.next());
        }*/
        
    }

}

Collection
    |--List:有序(存入和取出的顺序一致),元素都有索引(角标),元素可以重复。
    |--Set:元素不能重复,无序。

 

import java.util.ArrayList;
import java.util.List;
/**
 * 
List:特有的常见方法:有一个共性特点就是都可以操作角标。
    
1,添加
    void add(index,element);
    void add(index,collection);

2,删除;
    Object remove(index):

3,修改:
    Object set(index,element);
    
4,获取:
    Object get(index);
    int indexOf(object);获取指定元素的索引
    int lastIndexOf(object);
    List subList(from,to);
 *
 *
 */
public class ListDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        List list = new ArrayList();
        show(list);
    }

    public static void show(List list) {
        
        //添加元素
        list.add("abc1");
        list.add("abc2");
        list.add("abc3");
        System.out.println(list);//[abc1, abc2, abc3]
        
        //插入元素,在列表的指定位置插入元素    
        list.add(1,"abc9");
        
        System.out.println(list);//[abc1, abc9, abc2, abc3]
        
        //删除元素。
        System.out.println("remove:"+list.remove(2));//remove:abc2
        
        //修改元素。
        System.out.println("set:"+list.set(1, "abc8"));//set:abc9
        
        //获取元素。
        System.out.println("get:"+list.get(0));//get:abc1
        System.out.println(list);//[abc1, abc8, abc3]
        //获取子列表。
        System.out.println("sublist:"+list.subList(1, 3));//sublist:[abc8, abc3]
        //根据对象获取位置
        System.out.println(list.indexOf("abc8"));//1
        System.out.println(list.lastIndexOf("abc3"));//2
        System.out.println(list);//[abc1, abc8, abc3]
    }
}

 

List的遍历方式以及使用,使用Iterator接口的子接口ListIterator来完成在迭代中对集合元素进行的增删改查,不会抛出并发修改的异常

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;


public class ListDemo2 {

    /**
     * @param args
     */
    public static void main(String[] args) {

        List list = new ArrayList();
        showListIterator(list);
    }
    
    /**
     * 可以使用Iterator接口的子接口ListIterator来完成在迭代中对集合元素进行的增删改查,不会抛出并发修改的异常
     * 线程只操作迭代对象,不修改集合,这就不是并发的操作,是迭代对象ListIterator中自己的增删改方法,而不是调用集合中的方法
     * @param list
     */
    public static void showListIterator(List list){
        list.add("abc1");
        list.add("abc2");
        list.add("abc3");
        list.add("abc4");
        list.add("abc5");
        System.out.println("list:"+list);
    
        ListIterator it = list.listIterator();
        while(it.hasNext()){
            Object obj = it.next();
            if(obj.equals("abc4")){
                //it.add("abc9");//不是list.add
                it.set("abc9");
            }
            else
                System.out.print(" "+obj);
        }
        System.out.print("\n");
        System.out.println("********************************");
        //System.out.println("hasnext:"+it.hasNext());
        //System.out.println("hasPrevious:"+it.hasPrevious());
        //System.out.println("previous:"+it.previous());
        //逆向遍历
        while(it.hasPrevious()){
            System.out.print(" "+it.previous());//输出 abc5 abc9 abc3 abc2 abc1
        }
        System.out.print("\n");
        System.out.println("********************************");
        System.out.println(list);
        
    }
    /**
     * java.util.ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常
     * 集合和迭代器同时对元素进行修改,就会产生异常,一个线程对collection集合迭代,另一个对Collection进行修改的时候,
     * 就会出现上面的异常
     * @param list
     */
    public static void showConcurrentModificationException(List list){
        list.add("abc1");
        list.add("abc2");
        list.add("abc3");
        System.out.println("list:"+list);
    
        Iterator it = list.iterator();
        while(it.hasNext()){
            Object obj = it.next();//java.util.ConcurrentModificationException
                            //在迭代器过程中,不要使用集合操作元素,容易出现异常。
                        //可以使用Iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作。 
            if(obj.equals("abc2")){
                list.add("abc9");
            }
            else
                System.out.println("next:"+obj);
        }
        System.out.println(list);
        
    }
    /**
     * List集合的遍历,下面两种方法都可以
     * @param list
     */
    public static void show(List list) {
        
        list.add("abc1");
        list.add("abc2");
        list.add("abc3");
        list.add("abc4");
        //第一种使用iterator
        Iterator it = list.iterator();
        while(it.hasNext()){
            System.out.println("next:"+it.next());
        }
        
        //list特有的取出元素的方式之一。
        
        for(int x=0; x<list.size(); x++){
            System.out.println("get:"+list.get(x));
        }
    }

}

List:
    |--Vector:内部是数组数据结构,是同步的。增删,查询都很慢!
    |--ArrayList:内部是数组数据结构,是不同步的。替代了Vector。查询的速度快。
    |--LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。

Vector:

 

import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;

public class VectorDemo {

    /**Enumeration枚举接口的功能和Iterator迭代器接口的功能是重复的,Iterator接口添加了一个可选的移除方法,并使用较短的方法名
     * java1.2开始,使用Iterator替代Enumeration
     * @param args
     */
    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("nextelment:"+en.nextElement());
        }
        
        Iterator it = v.iterator();
        
        while(it.hasNext()){
            System.out.println("next:"+it.next());
        }
        
    }

}

 

ArrayList

package cn.itcast.p.bean;

public class Person  {

    private String name;
    private int age;
    
    
    public Person() {
        super();
        
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String toString(){
        return name+":"+age;
    }
 
  }
}
import java.util.ArrayList;
import java.util.Iterator;

import cn.itcast.p.bean.Person;

public class ArrayListTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ArrayList<Person> al = new ArrayList<Person>();
        al.add(new Person("listP1",21));
        al.add(new Person("listP1",22));
        al.add(new Person("listP2",23));
        al.add(new Person("listP3",24));
        
        System.out.println(al);//[listP1:21, listP1:22, listP2:23, listP3:24]
        
        Iterator it = al.iterator();
        while(it.hasNext()){
            Person p = (Person) it.next();
            System.out.println(p.getName()+"--"+p.getAge());
        }
    }
}

输出:

[listP1:21, listP1:22, listP2:23, listP3:24]
listP1--21
listP1--22
listP2--23
listP3--24

 

 

 

 

LinkedList:
    addFirst();
    addLast():
    jdk1.6
    offerFirst();
    offetLast();


    getFirst();.//获取但不移除,如果链表为空,抛出NoSuchElementException.
    getLast();
    jdk1.6
    peekFirst();//获取但不移除,如果链表为空,返回null.
    peekLast():


    removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException.
    removeLast();
    jdk1.6
    pollFirst();//获取并移除,如果链表为空,返回null.
    pollLast();
   

 

import java.util.Iterator;
import java.util.LinkedList;

public class LinkedListDemo {

    /**
     * @param args
     */
    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);
        
        System.out.println("使用getFirst---"+link.getFirst());//获取第一个但不删除。当链表为空的时候会抛出抛出NoSuchElementException
        System.out.println("使用getLast---"+link.getLast());//获取最后一个元素,当链表为空的时候会抛出抛出NoSuchElementException
        System.out.println("使用peekFirst---"+link.peekFirst());//获取第一个元素,当链表为为空的时候不会报异常
        System.out.println("使用peekLast---"+link.peekLast());//获取最后一个元素
        
//        System.out.println("使用link.removeFirst---"+link.removeFirst());//获取第一个元素但是会删除。abc4,当链表为空的时候会抛出抛出NoSuchElementException
//        System.out.println("使用removeFirst---"+link.removeFirst());//abc3
//        System.out.println("使用removeLast---"+link.removeLast());//获取最后一个元素,并移除abc1
        System.out.println("使用pollFirst---"+link.pollFirst());//获取第一个元素并从集合中移除(1.6,出来的新方法,当链表为为空的时候不会报异常)
        System.out.println("使用pollFirst---"+link.pollFirst());
        System.out.println("使用pollLast---"+link.pollLast());//获取最后一个元素并从集合中移除
        System.out.println("使用pollLast---"+link.pollLast());
//        while(!link.isEmpty()){
//            System.out.println(link.removeLast());
//        }
        
        
        System.out.println(link);
//        Iterator it = link.iterator();
//        while(it.hasNext()){
//            System.out.println(it.next());
//        }
    }

}

Set:元素不可以重复,是无序。
    Set接口中的方法和Collection一致。
    |--HashSet: 内部数据结构是哈希表 ,是不同步的。
        如何保证该集合的元素唯一性呢?
        是通过对象的hashCode和equals方法来完成对象唯一性的。
        如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
        如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
        如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。
        记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。
        一般情况下,如果定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals,hashCode方法。
        建立对象判断是否相同的依据。

 

 

package cn.itcast.p.bean;

public class Person /*extends Object*/ implements Comparable {

    private String name;
    private int age;
    
    
    public Person() {
        super();
        
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String toString(){
        return name+":"+age;
    }
    
    //判断人的hash值是否相同
    @Override
    public int hashCode() {
    System.out.println(this+".......hashCode"+name.hashCode()+age);
        return name.hashCode()+age*27;
//        return 100;
    }
    
    //判断人的内容是否相同
    @Override
    public boolean equals(Object obj) {
        if(this == obj)
            return true;
        if(!(obj instanceof Person))
            throw new ClassCastException("类型错误");
        System.out.println(this+"....equals....."+obj);
        Person p = (Person)obj;
        return this.name.equals(p.name) && this.age == p.age;
    }
 
    }
    
}

 

 

package cn.itcast.p4.hashset.test;

import java.util.HashSet;
import java.util.Iterator;

import cn.itcast.p.bean.Person;


/*
 * 往hashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人。视为相同元素。
 */
public class HashSetTest {

    /**
     * @param args
     */
    public static void main(String[] args) {

        
        HashSet hs = new HashSet();
        
        /*
         * HashSet集合数据结构是哈希表,所以存储元素的时候,我们需要覆盖hashCode方法和equal方法,来确保放入的对象的唯一性
         * 使用的元素的hashCode方法来确定位置,如果位置相同,
         * 在通过元素的equals来确定是否相同,如果相同的话,就不往set里面存
         */
        
        hs.add(new Person("lisi4",24));
        hs.add(new Person("lisi7",27));
        hs.add(new Person("lisi1",21));
        hs.add(new Person("lisi9",29));
        hs.add(new Person("lisi7",27));
        
        
        Iterator it = hs.iterator();
        
        while(it.hasNext()){
            Person p = (Person)it.next();
            //System.out.println(p);
            System.out.println(p.getName()+"...."+p.getAge());
        }
    }

}

 

 

java容器---集合总结

标签:style   blog   color   os   io   使用   java   strong   ar   

原文地址:http://www.cnblogs.com/200911/p/3948436.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!