黑馬程序員_Java集合Collection

------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! -------

1.Collection詳解

    集合的特點:用於存儲對象的容器(存儲對象的引用),集合的長度是可變的,集合中不可以存儲基本數據類型值

/*
person p = new person();
ArrayList a = new ArrayList();
al.add(p);//不表示將p這個對象放進了al這個容器裏了 表示了將p這個對象的地址放進al容器裏使al容器指向對象p
容器中不可能存放的是對象的實體,只能存放對象的地址
*/
    集合與數組的區別:
            集合中可以存儲任意的對象,且長度是可變的
            數組中只能存儲同一類型的數據,且長度是不可變的。

1.1 Collection的常用方法:

    添加元素 boolean add(Object);
public static void addDemo() {
    ArrayList a1 = new ArrayList();
    a1.add("java01");
    a1.add("java02");
    a1.add("java03");
    a1.add("java04");
    System.out.println(a1);//可以直接打印集合
}
    刪除元素 boolean remove(Object);   返回的是boolean.(List集合下也可以通過指定的角標來刪除某個對象,返回的是被刪除的那個對象)
public static void deleteDemo() {
    ArrayList a1 = new ArrayList();
    a1.add("java01");
    a1.add("java02");
    a1.add("java03");
    a1.add("java04");
    boolean b = a1.remove("java03");
    System.out.println(a1);
    System.out.println(b);
}

    清空元素:void clear();如果集合不支持該方法會拋出該異常:UnsupportedOperationException

public static void clearDemo() {
    ArrayList a1 = new ArrayList();
    a1.add("java01");
    a1.add("java02");
    a1.add("java03");
    a1.add("java04");
    a1.clear();
    System.out.println(a1);
}
    判斷某元素是否存在:boolean contains(Object)

public static void containsDemo() {
    ArrayList a1 = new ArrayList();        
    a1.add("java01");
    a1.add("java02");
    a1.add("java03");        
    a1.add("java04");
    boolean b = a1.contains("java03");
    System.out.println("java03是否存在:"+b);
}
    獲取集合中元素的個數:int size();

public static void sizeDemo() {
ArrayList a1 = new ArrayList();
    a1.add("java01");
    a1.add("java02");
    a1.add("java03");
    a1.add("java04");
    int a = a1.size();
    System.out.println("size:"+a);
}
    判斷集合是否爲空:boolean isEmpty();
public static void isEmptyDEmo() {
    ArrayList a1 = new ArrayList();
    a1.add("java01");
    a1.add("java02");
    a1.add("java03");
    a1.add("java04");
    boolean b = a1.isEmpty();
    System.out.println("集合是否爲空?:"+b);
}
    取交集:al1中只會保留和al2中相同的元素,如果沒有交集就爲空:boolean retainAll(Object)
public static void retainAllDemo() {
    ArrayList al1 = new ArrayList();
    al1.add("java01");
    al1.add("java02");
    al1.add("java03");
    al1.add("java04");
        
    ArrayList al2 = new ArrayList();
    al2.add("java01");
    al2.add("java02");
    al2.add("java05");
    al2.add("java06");
        
    //boolean b = al1.retainAll(al2);
    //System.out.println(b);
    System.out.println(al1);
    System.out.println(al2);
        
        
    boolean b = al1.removeAll(al2);//把相同的刪除
    System.out.println(b);
    System.out.println(al1);
}

1.2 特殊方法迭代器

取出集合中的元素:Iterator<e>  iterator();(返回的是一個Iterator接口)

    Iterator接口中的方法:
   判斷還有沒有元素:boolean hasNext()
   迭代下一個元素:E next();
         刪除元素:void remove()
public static void iteratorDemo() {
    ArrayList al = new ArrayList();
    al.add("java01");
    al.add("java02");
    al.add("java03");
    al.add("java04");
    
    /*注意:
        在迭代的時候要判斷一次獲取一次,也就是判斷一次hasNext()一次,只能next()一次
        並且在迭代過程中不能使用集合的方法操作集合,會發生併發異常
    */
    Iterator it = al.iterator();
    while(it.hasNext()){
        System.out.println(it.next());
    }
    /*
    使用for可以節省空間
    for (Iterator it = al.iterator(); it.hasNext();) {
        if(it.next().equals("java03"))
            it.remove();
        }
        System.out.println(al);
    */
}

2 List詳解

    可變數組的原理:就是不斷的創建新的數組,將原數組加到新的數組中

|--List:元素是有序的(怎麼存的就怎麼取出來,順序不會亂),元素可以重複(角標1上有個3,角標2上也可以有個3)因爲該集合體繫有索引,
  |-- ArrayList:底層的數據結構使用的是數組結構(數組長度是可變的百分之五十延長)(特點是查詢很快,但增刪較慢)線程不同步
  |-- LinkedList:底層的數據結構是鏈表結構(特點是查詢較慢,增刪較快)
  |-- Vector:底層是數組數據結構 線程同步(數組長度是可變的百分之百延長)(無論查詢還是增刪都很慢,被ArrayList替代了)


2.1 ArrayList

List:特有的方法,凡是可以操作角標的方法都是該體系特有的方法

  boolean add(int index, E element)
  boolean addAll(index,Collection)

public static void List_add(){
    ArrayList a1 = new ArrayList();
    a1.add("java");
    a1.add("php");//List集合中的元素可以重複
   a1.add(".net");
    System.out.println("原集合:"+a1);
    a1.add(1, "Flash");
    a1.add(0, "ps");    
    System.out.println(a1);
        
    ArrayList a2 = new ArrayList();
    a2.add("javascript");
    a2.add("3dMax");
    a2.add("IBM");
        
    a1.addAll(0, a2);
    System.out.println(a1);
}
 刪除指定位置的元素
  boolean remove(int index)

public static void List_remove(){
    ArrayList a1 = new ArrayList();
    a1.add("javascript");
    a1.add("php");
    a1.add("flash");
    System.out.println("原集合:"+a1);
        
    a1.remove(0);
    System.out.println(a1);
}
修改指定角標的元素  set(int index, E element)  返回的是修改的那個元素
public static void List_set() {
    ArrayList a1 = new ArrayList();
    a1.add("javascript");
    a1.add("php");
    a1.add(".net");
    System.out.println("原集合:"+a1);
        
    a1.set(1, "falsh");
    System.out.println(a1);
}

  get(int index)   返回列表中指定位置的元素
  subList(int fromIndex, int toIndex)    返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之間的部分元素。

public static void List_get() {
    ArrayList a1 = new ArrayList();
    a1.add("java");
    a1.add("php");
    a1.add("flash");
        
    System.out.println(a1.get(0));//獲取指定角標的元素,有了該方法就可以遍歷該集合中的所有元素
        
    System.out.println(a1.subList(1, 3));//獲取集合中某一部分的元素,包含頭不包含尾
}

List集合特有的迭代器:ListIterator(是Iterator的子接口)

注意:
 在迭代時,是不可以通過集合對象的方法操作集合中的元素
 因爲會發生ConcurrentModificationException異常(併發異常)
 所以,在迭代器時,只能用迭代器的方法造作元素
 因爲Iterator方法是有限的所以只能對元素進行判斷,取出,刪除的操作
 如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator
 該接口只能通過List集合的listIterator方法獲取

public class ListIteratorDemo {
    public static void main(String[] args) {
        ArrayList a1 = new ArrayList();
        a1.add("java01");
        a1.add("java02");
        a1.add("java03");
        a1.add("java04");

        System.out.println("原集合是:"+a1);
        
      /*在迭代過程中準備添加或者刪除元素
      Iterator it = al.iterator();
      while (it.hasNext()){
        Object obj = it.next();
        
        if (obj.equals("java02"))
        //al.add("java008");//會出現併發異常,因爲迭代器正在操作集合,不能再用集合的方法操作集合了
        it.remove();//將java02的引用從集合中刪除了
        System.out.println("obj:"+obj);
        }
        */    

    //只有List的listIterator有增,刪,改,查這些功能,因爲只有List有索引
       ListIterator li = a1.listIterator();
          while (li.hasNext()){
          if(li.next().equals("java02"))
          //li.add("java009");
          li.set("java006");
        }   
    }
}
Vector類和Enumeration接口:

Vector類是java語言提供的一種高級數據結構,可用於保存一系列對象,java不支持動態數組,Vector類提供了一種與動態數組相近的功能,如果我們不能預先確定要保存的對象的數目,或是需要方便獲取某個對象的存放位置時,Vector類都是一個不錯的選擇(因爲名字太長現在已經被取代)

import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;

public class Text {
    public static void main(String[] args) {
        int b = 0;
        Vector v = new Vector();
        System.out.println("Please Enter Number:");
        while(true){
            try {
                b = System.in.read();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if(b=='\r' || b=='\n'){
                break;//break用於跳出循環和switch
            }else{
                int num = b-'0';
                v.addElement(new Integer(num));
            }
        }
        int sum = 0;
        Enumeration en = v.elements();
        while(en.hasMoreElements()){
            Integer IntObject = (Integer)en.nextElement();
            sum+=IntObject.intValue();
        }
        System.out.println(sum);
        
    }
}
該列子中因爲不能確定用戶會輸入多少位數字,所以不能使用數組來存儲每一個數值,所以選擇集合,集合只能接受對象類型的數據

Vector:枚舉就是Vector特有的取出方式,跟迭代器很像(其實枚舉和迭代是一樣的) 已經被迭代器取代
public class VectorDemo {
    public static void main(String[] args) {
        Vector v = new Vector();
        v.add("java01");
        v.add("java02");
        v.add("java03");
        v.add("java04");

        for(Enumeration en = v.elements();en.hasMoreElements();){
            System.out.println(en.nextElement());
        }
    }

}

2.2 LinkedList

特有方法:  
    addFirst();在頭部添加元素      addLast();在尾部添加元素
    getFirst(); getLast(); 獲取元素但不刪除元素。如果集合中沒有元素,會出現NoSuchElementException
    removeFirst();   removeLast(); 獲取元素但是刪除元素。如果集合中沒有元素,會出現NoSuchElementException

在JDK1.6出現了替代方法
    offerFirst(); offerLast();
    peekFirst(); peekLast(); 獲取元素,但是元素不被刪除。如果集合中沒有元素,會返回null
     pollFirst(); pollLast(); 獲取元素,但是元素被刪除。如果集合中沒有元素,會返回null
public class LinkedListDemo {
    public static void main(String[] args) {
        LinkedList link = new LinkedList();
        link.add("java01");
        link.add("java02");
        link.add("java03");
        link.add("java04");

        while(!link.isEmpty()){
            System.out.println((link.removeLast()));
        }
    }

}

3 Set詳解

Set:元素是無序(存入和取出的順序不一定一致),元素不可以重複,因爲該集合體系沒有索引。Set集合的功能Collection是一致的,取出只有一種方式 就是迭代器
  ----HashSet:底層數據結構是哈希表,線程是非同步的(有個子類可以實現有序,LinkedHashSet(鏈表結構和has結構相結合))
  ----TreeSet:可以對Set集合中的元素進行排序(自然排序,由小到大) 底層的數據結構是二叉樹,線程不同步


3.1 HashSet集合

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

public class HashSetDemo {
    public static void main(String[] args) {
        HashSet hs = new HashSet();
        /*
        sop(hs.add("java01"));結果是true
        sop(hs.add("java01"));結果是false,因爲java01已經存在了就不在存了
        */
        hs.add("java01");
        hs.add("java02");
        hs.add("java02");//返回結果爲false,因爲集合中已經有java02了 就不在存了
        hs.add("java02");
        hs.add("java03");
        hs.add("java04");

        //set集合的取出只有一種方式 就是迭代器
        for (Iterator it = hs.iterator(); it.hasNext();) {
            System.out.println(it.next()); 
        }
    }
}
 HashSet是如何保證元素的唯一性的(判斷元素相同的依據): 是通過元素的兩個方法,hashCode和equals來完成
  -如果元素的HashCode值相同,纔會判斷equals是否爲true
  -如果元素的hashcode值不同,不會調用equals
對於判斷元素是否存在,以及刪除等操作,依賴的方法是元素的hashcode和equals方法

往hashSet集合中存入自定義對象.姓名和年齡相同爲同一個人,重複元素。
import java.util.*;
public 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("a2",12));
        hs.add(new Person("a4",14));
        
        Iterator it = hs.iterator();
        while (it.hasNext()){
            Person p = (Person)it.next();
            System.out.println(p.getName()+"::"+p.getAge());
        }
    }
}

//以後開發中描述事物時,都要有複寫hashCode和equals方法,因爲可能這個對象會存儲到HashSet集合中
class Person{
    private String name;
    private int 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 Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    
    //用於計算哈希值是否相等,
    public int hashCode(){
        //return 60;//很多重複比較,導致哈希值都相同,要調用equals方法比較是不是同一個對象
        return name.hashCode()+age*27;//*27是爲了保證哈希值的唯一性,可以任何值都可以.每個字符串都有自己的哈希值
    }
    //用於比較兩個對象是否相等
    public boolean equals(Object obj){
        if (!(obj instanceof Person))
            return false;
        
        Person p = (Person)obj;
        return this.name.equals(p.name) && this.age == p.age;
    }
}
 記住:如果元素要存儲到HashSet集合中,必須覆蓋hashCode方法和equals方法。
一般情況下,如果定義的類會產生很多對象,比如人,學生,書,通常都需要覆蓋equals,hashCode方法。建立對象判斷是否相同的依據。

LinkedHashSet(鏈表結構和has結構相結合)):變集合中的元素變得有序(這裏說的有序不是指排序而是指怎麼存的順序跟取出來的順序是一樣的)
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;

public class LinkedHashSetDemo {
    public static void main(String[] args) {

        HashSet hs = new LinkedHashSet();
        
        hs.add("hahah");
        hs.add("hehe");
        hs.add("heihei");
        hs.add("xixii");
        hs.add("hehe");
        
        Iterator it = hs.iterator();
        
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

3.2 TreeSet

import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetDemo {
    public static void main(String[] args) {
        TreeSet ts = new TreeSet();

        ts.add("cab");//打印結果是對照字符編碼表中對於的數值的大小排序
        ts.add("aab");
        ts.add("dab");
        ts.add("Bab");

        Iterator it = ts.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
    }
}
判斷元素唯一性的方式:就是根據比較方法的返回結果是否是0,是0,就是相同元素,不存。

TreeSet對元素進行排序的方式一:讓元素自身具備比較功能,元就需要實現Comparable接口。覆蓋compareTo方法。

需求:往TreeSet集合中存儲自定義對象。安照人的年齡進行排序
import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetTest {
    public static void main(String[] args) {
        TreeSet ts = new TreeSet();//往TreeSet集合中的對象會自動排序的,所以往裏存的對象必須要具有比較性

        ts.add(new Person("jianqing",18));
        ts.add(new Person("jianfeng",14));
        ts.add(new Person("jianhuo",15));
        ts.add(new Person("jianguang",17));

        Iterator it = ts.iterator();
        while (it.hasNext()){
            Person p = (Person)it.next();
            System.out.println(p.getName()+"...."+p.getAge());
        }
    }
}
//該接口強制讓學生具備比較性
class Person implements Comparable{
    private String name;
    private int age;
    Person(String name,int age){
        this.name = name;
        this.age = age;
    }
    
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
    
    //實現了Compareble要覆蓋該方法,這個方法在底層會自動調用,該方法可以給自定義對象進行排序
    public int compareTo(Object obj){
        if (!(obj instanceof Person))
            throw new RuntimeException("不是人");
        Person p  = (Person)obj;
        if(this.age>p.age)
            return 1;
        if(this.age == p.age){
            return this.name.compareTo(p.name);//排序時,當主要條件相同時,一定要判斷下次要條件。如果這裏返回0 說明兩個對象是同一個對象
        }
        return -1;
    }

    public boolean equals(Object obj){
        if (!(obj instanceof Person))
            return false;

        Person p = (Person)obj;
        return this.name.equals(p.name) && this.age == p.age;
    }
}
當元素自身不具備比較性,或者具備的比較性不是所需要的(不能去改Person類的代碼,有可能不是自己寫的),這時需要讓容器自身具備比較性
可以使用TreeSet集合第二種排序方式二:讓集合自身具備比較功能,定義一個類實現Comparator接口,覆蓋compare方法。將該類對象作爲參數傳遞給TreeSet集合的構造函數。

當兩種排序都存在時,以比較器爲主(定義一個類,實現comparator接口,覆蓋compare方法

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetTest{
    public static void main(String[] args) {
        TreeSet ts = new TreeSet(new MyCompare());//將比較器對象作爲參數傳遞給TreeSet集合的構造函數。

        ts.add(new Person("jianqing",18));
        ts.add(new Person("jianfeng",14));
        ts.add(new Person("jianhuo",15));
        ts.add(new Person("jianguang",17));

        Iterator it = ts.iterator();
        while (it.hasNext()){
            Person p = (Person)it.next();
            System.out.println(p.getName()+"...."+p.getAge());
        }
    }

}
class Person implements Comparable{//該接口強制讓學生具備比較性
    private String name;
    private int age;
    Person(String name,int age){
        this.name = name;
        this.age = age;
    }

    public int compareTo(Object obj){//實現了Compareble後這個方法在底層會自動調用
        if (!(obj instanceof Person))
            throw new RuntimeException("不是人");
        Person p  = (Person)obj;
        if(this.age>p.age)
            return 1;
        if(this.age == p.age){
            return this.name.compareTo(p.name);
        }
        return -1;
    }
    
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }


    public boolean equals(Object obj){
        if (!(obj instanceof Person))
            return false;

        Person p = (Person)obj;
        return this.name.equals(p.name) && this.age == p.age;
    }
}
//定義一個比較器,按照姓名排序
class MyCompare implements Comparator{
    public int compare(Object o1,Object o2){
        Person s1 = (Person)o1;
        Person s2 = (Person)o2;
        int num = s1.getName().compareTo(s2.getName());

        if(num==0){
            return (new Integer(s1.getAge()).compareTo(new Integer(s2.getAge())));
            /*
            if(s1.getAge()>s2.getAge())
                return 1;
            if(s1.getAge()==s2.getAge())
                return 0;
            return -1;
            */
        }
        return num;
    }
}

4 Map集合

Map集合(雙列集合):該集合存儲鍵值對,一對一對往裏存,而且要保證鍵的唯一性

Map
  |--Hashtable:底層是哈希表數據結構,不可以存入null鍵null值,該集合 線程同步的,效率低
  |--Properties:用來存儲鍵值對型的配置文件的信息,可以和IO技術相結合。
  |--HashMap:底層也是哈希表數據結構,可以存入null鍵null值,該集合 不同步的,效率高
  |--TreeMap:底層是二叉樹數據結構,線程不同步,可以用於map集合中的鍵進行排序



添加
    put(K key,V value)
    putAll(Map<? extends K,?extends V> m)

刪除
    clear() 清除集合中的所有鍵和值
    remove(Object key) 傳入鍵,刪除相應的值,結果會返回相應的值

獲取
    get(Object key) 返回指定鍵的值,如果沒有該鍵返回null
    size() 返回該集合的長度
    Collection values() 返回集合中的所有值並且保存到Collection集合中

判斷
    containsKey(Object key) 判斷 該鍵是否存在
    containsValue(Object value) 判斷該值是否存在
    isEmpty() 判斷集合是否爲空

跟Set很像,Set底層就是使用了Map集合

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class MapDemo {
    public static void main(String[] args) {
        
        Map<Integer,String> map1 = new HashMap<Integer,String>();
        map1.put(1,"huangjianfeng1");
        //map.put(1,"huangjianfeng1");//存相同鍵,值會被覆蓋
        map1.put(2,"huangjianfeng2");
        map1.put(3,"huangjianfeng3");
        map1.put(4,"huangjianfeng4");
        //map.clear();
        System.out.println(map1);
        
        
        
        
        Map<String,String> map = new HashMap<String,String>();

        //添加元素
        map.put("1","huangjianfeng1");
        map.put("2","huangjianfeng2");
        map.put("3","huangjianfeng3");


        map.put("04",null);//null除了在HashTable之外,可以作爲鍵或者值
        System.out.println(map.get("04"));
        


        //刪除
        System.out.println(map.remove("1"));//刪除1號鍵,並且能返回1號鍵對應的值,如果沒有對應的鍵,則返回null
        //map.clear();

        //判斷
        System.out.println(map.containsKey("2"));
        System.out.println(map.containsValue("huangjianfeng1"));


        //獲取
        System.out.println(map.get("1"));//,如果有該鍵,返回該鍵對應的值,如果沒有該鍵 返回null
        System.out.println(map.size());
        

        //獲取map集合中所有的值
        Collection<String> coll = map.values(); //values()方法返回的是一個Collection集合
        System.out.println(coll);//用迭代



        //添加元素,如果出現添加時相同的鍵,那麼後添加的值會覆蓋原有鍵對應值,並put方法會返回被覆蓋的值
        System.out.println(map.put("1","huangjianfeng1"));
        System.out.println(map.put("1","huangjianfeng2"));
    }
}

map集合中元素的取出

map集合的取出原理:將map集合轉成set集合,在通過迭代器取出

map集合的第一種取出方式:Set<k> keySet:將map中所有的鍵存入到Set集合,因爲set具備迭代器,所以可以迭代方式取出所有的鍵,在根據get方法,獲取每一個鍵對應的值

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Map_KeySet {
    public static void main(String[] args) {
        
        Map<Integer,String> map = new HashMap<Integer,String>();

        map.put(1,"huangjianfeng1");
        map.put(2,"huangjianfeng2");
        map.put(3,"huangjianfeng3");

        //先通過該方法keySet()(返回的就是set集合)獲取map集合的所有鍵 存到set集合中
        Set<Integer> keySet = map.keySet();
        
        //有了Set集合,就可以獲取其迭代器
        for (Iterator<Integer> it = keySet.iterator();it.hasNext() ; ){
            Integer key = it.next();
            //有了鍵就可以通過map集合的get方法獲取對應的值
            String value = map.get(key);
            System.out.println(key+"="+value);
        }
    }
}












發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章