總網頁瀏覽量

2012年5月21日 星期一

JAVA 集合(1) List

集合類
物件導向對事物都是以物件的形式,所以為了方便對多個物件的操作,就對物件進行存儲,集合就是存儲物件最常用的一 種方式

陣列和集合類同是容器,有何不同?
陣列雖然也可以存儲物件,但長度是固定的
集合長度是可變的。 陣列中可以存儲基底資料型別,集合只能存儲物件,集合可以存儲不同類型的物件。





























集合框架中的常用介面
Collection介面有兩個子介面:
List(列表),Set(集)
List:可存放重複元素,元素存取是有序
Set:不可以存放重複元素,元素存取是無序

基本方法使用:
class Hello{
    public static void main(String[] args){
        //創建一個容器 使用Collection介面的子類
        ArrayList a = new ArrayList();
        a.add("x");
        a.add("y");
        a.add("z");
        sop(a.contains("x"));  //T
        sop(a.isEmpty());   //F
        sop(a);  //[x, y]
        a.remove("y");
        sop(a); //[x]
        sop(a.clear());//[]
}

class Hello{
    public static void main(String[] args){
        //創建一個容器 使用Collection介面的子類
        ArrayList a = new ArrayList();
        a.add("x");
        a.add("y");
        a.add("z");

        ArrayList b = new ArrayList();
        b.add("x");
        sop(a);  //[x, y, z]
        a.retainAll(b); //保留交集
        sop(a); //[x]
       
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

Iterator
class Hello{
    public static void main(String[] args){
        ArrayList a = new ArrayList();
        a.add("x");
        a.add("y");
        a.add("z");
        Iterator it = a.iterator();//返回一個Iterator介面的子類物件
       
        sop(it.next()); //x
        sop(it.next()); //y
        sop(it.next()); //z
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}


class Hello{
    public static void main(String[] args){
        ArrayList a = new ArrayList();
        a.add("x");
        a.add("y");
        a.add("z");
        //返回一個Iterator介面的子類物件
        //用於取出集合中的元素
        Iterator it = a.iterator();
       
        while(it.hasNext()){
            sop(it.next()); //x y z
        }
       
        it.remove();//移除最後一個元素
        sop(a);
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}
Collection(介面)
l   List(介面)
n   有序(依存入的順序),可重複,有索引
l   Set(介面)
n   無序,不可重複

List介面中常用類
l   Vector:執行緒安全(同步),但速度慢,已被 ArrayList替代
l   ArrayList:執行緒不安全(不同步),查詢速度快,但增加刪除慢,使用陣列
l   LinkedList:增刪速度快,查詢慢,使用鏈結串列

Set介面中常用類
l   HashSet:底層數據結構是hash table,而hashSet是如何保證元素唯一性,是通過元素的兩個方法,hashCodeequals方法來完成,如果元素的HashCode值相同,才會判斷equals是否為true,如果元素的hashCode值不同,不會調用equals
l   TreeSet:可以對Set集合中的元素進行排序,底層數據結構是二元樹,保證元素唯一性的依據,compareTo方法return 0
n   TreeSet排序的第一種方式,讓元素自身具備比較性,元素需要實現比較性,元素需要實現Comparable介面,覆寫comparTo方法,這種方法也成為元素的自然順序,或者叫作默認順序
n   TreeSet的第二種排序方式: 當元素本身不具備比較性,或者具備的比較性不是所需要的,這時就需要讓集合自身具備比較性。在集合初始化時,就有了比較方式,定義一個類別,實現Comparator介面,覆寫compare方法
n   當兩種排序都存在時,以比較器為主

class Hello{
    public static void main(String[] args){
        ArrayList a = new ArrayList();
        a.add("x");
        a.add("y");
        a.add("z");
        sop(a); //[x, y, z]
       
        a.add(1, "w");
        sop(a); //[x, w, y, z]
        a.remove(2); //移除索引2元素
        sop(a);//[x, w, z]
        a.set(2, "xyz");
        sop(a);//[x, w, xyz]
        sop(a.get(1));//w
       
        for(int x = 0; x <a.size(); x++){
            sop("a(" + x + ") = " + a.get(x));
        }      
        sop("index: " + a.indexOf("x"));//0
        List sub = a.subList(1, 2);
        sop(sub);//[w]
    }

List方法
l  
n   add(index, element);
n   addAll(index, Collection);
l  
n   remove(index);
l  
n   set(index, element);
l  
n   get(index);
n   subList(from, to);
n   listIterator();

class Hello{
    public static void main(String[] args){
        ArrayList a = new ArrayList();
        a.add("x");
        a.add("y");
        a.add("z");
        sop(a);//[x, y, z]
        Iterator it = a.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            if(obj.equals("x")){
                //a.add("w"); 發生異常 不可這樣用
                it.remove();//移除 x (it移除, a也移除)
                sop(obj);//x
            }
           
        }
        sop(a);//[y, z]
       
    }

List集合特有的迭代器,ListIteratorIterator的子介面
在迭代時,不可以通過集合物件的方法操作集合中的元素,會發生ConcurrentModificationException異,所以在迭代器時,只能用迭代器的方法操作元素,但其方法只有判斷、取出、移除等操作,如果想做其他操做,就需要使用其子介面,即ListIterator
該介面只通過List集合的ListIterator方法取得

ListIteratorhasNexthasPrevious方法
集合一開始指向null位置,所以hasNexttrue,而hasPreviousflase!!


如下:
class Hello{
    public static void main(String[] args){
        ArrayList a = new ArrayList();
        a.add("x");
        a.add("y");
        a.add("z");
        sop(a);//[x, y, z]
        Iterator it = a.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            if(obj.equals("x")){
                //a.add("w"); 發生異常 不可這樣用
                it.remove();//移除 x (it移除, a也移除)
                sop(obj);//x
            }
        }
        sop(a);//[y, z]
        ListIterator li = a.listIterator();
        while(li.hasNext()){
            Object obj = li.next();
            if(obj.equals("y")){
                li.set("y1");//修改元素
                li.add("x");//增加元素 x
            }
        }
        sop(a);//[y, x, z]
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}


Vector
class Hello{
    public static void main(String[] args){
        Vector v = new Vector();
        v.add("a");
        v.add("b");
        v.add("c");
        v.add("d");
        Enumeration en = v.elements();//vector的迭代器以被Iterator取代
        while(en.hasMoreElements()){
            sop(en.nextElement());
        }
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

LinkList
/*LinkedList方法
 * addFirst()
 * addList()
 * getFirst() 取得元素但不移除 如果集合中沒有元素 會出現NoSuchElementException
 * getLast()
 * removeFirst() 取得元素並移除 如果集合中沒有元素 會出現NoSuchElementException
 * removeLast()
 *
 * JDK1.6的替代方法 解決集合空異常
 * offerFirst()
 * offerLast()
 * peekFirst() 取得元素但不移除 集合為空返回null
 * peekLast()
 * pollFirst() 取得元素並移除 集合為空返回null
 * pollLast() 
 * */
class Hello{
    public static void main(String[] args){
        LinkedList link = new LinkedList();
        link.addFirst("a");
        link.addFirst("b");
        link.addFirst("c");
        link.addFirst("d");
       
        sop(link);//[d, c, b, a]
        sop(link.getFirst());//d
        sop(link.getLast());//a
        link.removeFirst();
        link.removeLast();
        sop(link);//[c, b]
        sop(link.size());//2
       
        while(!(link.isEmpty())){
            sop(link.removeFirst());//c, b
        }
       
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

使用LinkList模擬stack
class StackTest{
    private LinkedList link;
    public StackTest() {
        link = new LinkedList();
    }
    public void add(Object obj){
        link.addFirst(obj);
    }
    public Object get(){
        return link.removeFirst();
    }
    public boolean isNull(){
        return link.isEmpty();
    }
   
}

class Hello{
    public static void main(String[] args){
        StackTest link = new StackTest();
        link.add("a");
        link.add("b");
        link.add("c");
        while(!(link.isNull())){
            System.out.println(link.get()); //c, b, a
        }
    }
}

ArrayList去除重複元素
class Hello{
    public static void main(String[] args){
        ArrayList array = new ArrayList();
        array.add("a");
        array.add("a");
        array.add("a");
        array.add("b");
        array.add("b");
        array.add("c");
        sop(array); //[a, a, a, b, b, c]
       
        array = singleElement(array);
        sop(array); //[a, b, c]
    }
   
    public static ArrayList singleElement(ArrayList tempArray){
        ArrayList newArray = new ArrayList();
        Iterator it = tempArray.iterator();
        while(it.hasNext()){
            Object obj  = it.next();
            if(!(newArray.contains(obj))){
                newArray.add(obj);
            }
        }
        return newArray;
    }
   
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

List集合判斷元素是否相同,依據是元素的equals方法!!
將自定義物件存到ArrayList中,並去除重覆
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;
    }
    //object類的equals為位址比較 需自定義equals方法 才能夠判斷出相等物件
    public boolean equals(Object obj){
        if(!(obj instanceof Person)){
            return false;
        }else{
            Person p = (Person)obj;
            //使用string類的equals比較
            return this.name.equals(p.name) && this.age == p.age;
        }
    }
}

class Hello{
    public static void main(String[] args){
        ArrayList array = new ArrayList();
        array.add(new Person("kent", 20));
        array.add(new Person("hardy", 25));
        array.add(new Person("kemp", 22));
        array.add(new Person("kemp", 22));
        array.add(new Person("hardy", 25));
       
        array = singleElement(array);
        Iterator it = array.iterator();
       
        while(it.hasNext()){
            //Object obj = it.next();
            //Person p = (Person)obj;
            Person p = (Person)it.next();
            sop(p.getName() + ":: "  +  p.getAge());
        }
    }
    public static ArrayList singleElement(ArrayList a){
        ArrayList newA = new ArrayList();
        Iterator it = a.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            if(!(newA.contains(obj))){//contain會調用Person類中的equals方法
                newA.add(obj);
            }
        }
        return newA;
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

HashSet
class Hello{
    public static void main(String[] args){
        HashSet hs = new HashSet();
        hs.add("a");
        hs.add("b");
        hs.add("c");
        hs.add("d");
        hs.add("b");
        hs.add("d");
        sop(hs);//[d, b, c, a]  不可重覆 且無序
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

HashSet內存入自定義物件,檢查有無重覆元素
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;
    }
    //需先判斷hashcode是否一樣才會調用equals方法
    //如此才會去除重覆元素
    public int hashCode(){
        return name.hashCode() + age;//使用String類的hashCode()方法
    }
    public boolean equals(Object obj){
        if(!(obj instanceof Person)){
            return false;
        }else{
            Person p = (Person)obj;
            return this.name.equals(p.name) && this.age == p.age;
        }
    }
}
class Hello{
    public static void main(String[] args){
        HashSet hs = new HashSet();
        hs.add(new Person("a", 20));
        hs.add(new Person("b", 21));
        hs.add(new Person("c", 22));
        hs.add(new Person("d", 23));
        hs.add(new Person("c", 22));
       
        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);
    }
}

TreeSet
class Hello{
    public static void main(String[] args){
        TreeSet ts = new TreeSet();
        ts.add("d");
        ts.add("c");
        ts.add("b");
        ts.add("a");
        sop(ts); //[a, b, c, d]
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

TreeSet應用自定義類別,加入元素,並以年齡來排序,但是當主要條件相同時,一定要比較次要條件
//該介面強制讓Student具備比較性, 否則會發生異常
//因為其不具比較性
class Student implements Comparable{
    private String name;
    private int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
    public int compareTo(Object obj){
        if(!(obj instanceof Student)){
            throw new RuntimeException("不屬於此類");
        }
        Student s = (Student)obj;
        if(this.age > s.age){
            return 1;
        }else if(this.age == s.age){
            return this.name.compareTo(s.name);
        }else{
            return -1;
        }
    }
}

class Hello{
    public static void main(String[] args){
        TreeSet ts = new TreeSet();
        ts.add(new Student("a", 25));
        ts.add(new Student("b", 23));
        ts.add(new Student("c", 21));
        ts.add(new Student("d", 22));
       
        Iterator it = ts.iterator();
        while(it.hasNext()){
            Student s = (Student)it.next();
            //依年齡排序
            sop(s.getName() + ": " + s.getAge());// c: 21, d: 22, b: 23, a: 25
        }
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}


二元樹排序 依名稱排序
class Student implements Comparable{
    private String name;
    private int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
    public int compareTo(Object obj){
        if(!(obj instanceof Student)){
            throw new RuntimeException("不屬於此類");
        }
        Student s = (Student)obj;
        if(this.age > s.age){
            return 1;
        }else if(this.age == s.age){
            return this.name.compareTo(s.name);
        }else{
            return -1;
        }
    }

}

public class Main{
    public static void main(String[] args){
        TreeSet ts = new TreeSet(new MyCompare());
        ts.add(new Student("a", 25));
        ts.add(new Student("b", 23));
        ts.add(new Student("c", 21));
        ts.add(new Student("d", 22));
        ts.add(new Student("a", 15));
        ts.add(new Student("d", 40));
       
        Iterator it = ts.iterator();
        while(it.hasNext()){
            Student s = (Student)it.next();
            sop(s.getName() + ": " + s.getAge());
            //a: 15, a: 25, b: 23, c: 21, d: 22, d: 40
            //name排序,name相等在依age排序
        }
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

class MyCompare implements Comparator{
    public int compare(Object o1, Object o2){
        Student s1 = (Student)o1;
        Student s2 = (Student)o2;
        int num =  s1.getName().compareTo(s2.getName());
        if (num == 0){
            /**if(s1.getAge() >s2.getAge()){
                return 1;
            }
            if(s1.getAge() == s2.getAge()){
                return 0;
            }
            return -1;*/
            //使用Integer類的compareTo方法
            return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
        }
        return num;
    }
}

字串本身具備比較性,但是他的方法不是所需要的,所以需要使用比較器,先比較長度,若長度相等再比較字串大小
public class Main{
    public static void main(String[] args){
        TreeSet ts = new TreeSet(new StringLengthCompare());
        ts.add("ajij");
        ts.add("bc");
        ts.add("cb");
        ts.add("cweef");
        ts.add("dwwsw");
       
        Iterator it = ts.iterator();
        while(it.hasNext()){
            sop(it.next());
        }
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

class StringLengthCompare implements Comparator{
    public int compare(Object o1, Object o2){
        String s1 = (String)o1;
        String s2 = (String)o2;
       
        int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
        //長度相等比次要元素
        if(num == 0){
            return s1.compareTo(s2);
        }
        return num;
    }
}

泛型
發生異常現象,使用泛型解決,JDK1.5出現的,用於解決安全問題
public class Main{
    public static void main(String[] args){
        ArrayList al = new ArrayList();
        al.add("ajij");
        al.add("ceccsd");
        al.add("wcegess");
        al.add(4); //發生異常
       
        Iterator it = al.iterator();
        while(it.hasNext()){
            String s = (String)it.next();
            sop(s);
        }
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

泛型好處
將運行時期出現問題classCastException,轉移到編譯時期,方便解決問題,讓運行時期問題減少,提升安全性,同時避免了強制轉型的麻煩

修改上例
public class Main{
    public static void main(String[] args){
        ArrayList<String> al = new ArrayList<String>();
        al.add("ajij");
        al.add("ceccsd");
        al.add("wcegess");
       
        Iterator<String> it = al.iterator();
        while(it.hasNext()){
            String s = it.next();
            sop(s);
        }
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

泛型格式,通過<>來定義要操作的引用數據類型,通常在集合框架中很常見,只要看到<>都要,<>用來接收類型,當使用集合時,將集合中要存儲的數據類型作為參數傳遞到<>中即可

比較字串長度,長度一樣再比較字串大小
public class Main{
    public static void main(String[] args){
        TreeSet<String> ts = new TreeSet<String>();
        ts.add("ajij");
        ts.add("ceccsw");
        ts.add("ajia");
        ts.add("ceccsd");
        ts.add("wcegess");
       
        Iterator<String> it = ts.iterator();
        while(it.hasNext()){
            String s = it.next();
            sop(s);
            // ajia, ajij, ceccsd, ceccsw, wcegess
        }
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}
class LenComparator implements Comparator<String>{
    public int compare(String o1, String o2){
        int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));
        if(num == 0)
            return o1.compareTo(o2);
        return num;
    }
}


泛型前作法
class Worker {

}
class Student{
   
}
class Tool{
    private  Object obj;
    public void setObject(Object obj){
        this.obj = obj;
    }
    public Object getObject(){
        return obj;
    }
}

public class Main{
    public static void main(String[] args){
        Tool t = new Tool();
        t.setObject(new Worker());
        Worker w = (Worker)t.getObject();
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

使用泛型
當類別中要操作的引用數據類型不確定時,早期定義Object來擴展,現在則定義泛型來完成擴展
class Tool<E>{
    private  E obj;
    public void setObject(E obj){
        this.obj = obj;
    }
    public E getObject(){
        return obj;
    }
}
public class Main{
    public static void main(String[] args){
        Tool<Worker> u = new Tool<Worker>();
        u.setObject(new Worker());
        Worker worker = u.getObject();
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

泛型類別定義,在整個類別有效,如果被方法使用,那泛型類別的物件要明確操作具體類型後,所有操作的類型就固定了,為了讓不同方法可以操作不同類型,而且類型不確定,那可以將泛型定義在方法上
class Demo<T>{
    public void show(T t){
        System.out.println("show: " + t);
    }
    public void print(T t){
        System.out.println("print: " + t);
    }
}

public class Main{
    public static void main(String[] args){
        Demo<Integer> d = new Demo<Integer>();
        d.show(new Integer(4));
        d.print(9);
    }
}

改用方法定義泛型,更具彈性
class Demo{
    public <T> void show(T t){
        System.out.println("show: " + t);
    }
    public <Q> void print(Q q){
        System.out.println("print: " + q);
    }
}

public class Main{
    public static void main(String[] args){
        Demo d = new Demo();
        d.show(new Integer(4));
        d.print("123");
    }
}

靜態方法不可以訪問類別中定義的泛型,如果靜態方法操作的應用數據類型不確定,可以將泛型定義在方法上
class Demo{
    public static <W> void method(W t){
        System.out.println("method: " + t);
    }
}
public class Main{
    public static void main(String[] args){
        Demo d = new Demo();
        Demo.method("Test");
    }
}

泛型定義在介面上
interface Inter<T>{
    void show(T t);
}
class InterImpl<T> implements Inter<T>{
    public void show(T t){
        System.out.println("Show: " + t);
    }
}
public class Main{
    public static void main(String[] args){
        InterImpl i = new InterImpl();
        i.show(new Integer(111));
    }
}

<?>
public class Main{
    public static void main(String[] args){
        ArrayList<String> a1 = new ArrayList<String>();
        a1.add("abc");
        a1.add("abc1");
        a1.add("abc2");
       
        ArrayList<Integer> a2 = new ArrayList<Integer>();
        a2.add(1);
        a2.add(2);
        a2.add(3);
       
        print(a1);
        print(a2);
    }
    public static void print(ArrayList<?> arrayList){
        Iterator<?> it = arrayList.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

<?>: 通配符,也可以理解為佔位符
泛型的限定
? extends E: 可以接收E類型或E的子類型,上限
? super E: 可以接收E類型或E的父類型,下限

public class Main{
    public static void main(String[] args){
        ArrayList<Person> al = new ArrayList<Person>();
        al.add(new Person("a"));
        al.add(new Person("b"));
        al.add(new Person("c"));
        printColl(al);
       
        ArrayList<Student> ala = new ArrayList<Student>();
        ala.add(new Student("ddd"));
        ala.add(new Student("b2"));
        ala.add(new Student("c3"));
        printColl(al);
    }
   
    //泛型的限定
    public static void printColl(ArrayList<? extends Person> al){
        Iterator<? extends Person> it = al.iterator();
        while(it.hasNext()){
            System.out.println(it.next().getName());
        }
    }
}

class Person{
    private String name;
    Person(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

class Student extends Person{
    Student(String name){
        super(name);
    }
}


使用TreeSet來運用泛型擴展
public class Main{
    public static void main(String[] args){
        TreeSet<Student> ts = new TreeSet<Student>(new Comp());
        ts.add(new Student("stuent--1"));
        ts.add(new Student("stuent--5"));
        ts.add(new Student("stuent--3"));
        ts.add(new Student("stuent--2"));
        ts.add(new Student("stuent--4"));

        TreeSet<Worker> ts1 = new TreeSet<Worker>(new Comp());
        ts1.add(new Worker("work---5"));
        ts1.add(new Worker("work---3"));
        ts1.add(new Worker("work---1"));
        ts1.add(new Worker("work---2"));
        ts1.add(new Worker("work---4"));       
       
        Iterator<Student> it = ts.iterator();
        while(it.hasNext()){
            System.out.println(it.next().getName());
        }
        Iterator<Worker> it1 = ts1.iterator();
        while(it1.hasNext()){
            System.out.println(it1.next().getName());
        }
    }
}
class Comp implements Comparator<Person>{
    public int compare(Person p1, Person p2){
        return p2.getName().compareTo(p1.getName());
    }
}
class Person{
    private String name;
    Person(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

class Student extends Person{
    Student(String name){
        super(name);
    }
}

class Worker extends Person{
    Worker(String name){
        super(name);
    }
}

Map集合
該集合存儲鍵值對,而且要保證鍵的唯一性
l   增加
n   put(K key, V value)
n   putAll(Map<? extneds K, ?extends V> m)
l   刪除
n   clear()
n   remove(Object key)
l   判斷
n   constainsKey(Object key)
n   constainsVaule(Object value)
n   isEmpty()
l   獲取
n   value get(Object key)
n   size()
n   values()
n   entrySet()
n   keySet()

Map子類
l   Hashtable: 底層是雜湊表數據結構,不可存入nullnull值,該集合是線程同步
l   HashMap: 底層是雜湊表數據結構,允許存入nullnull值,該集合是不同步
l   TreeMap: 底層是二元樹數據結構,線程不同步,可以用於map集合中的鍵進行排序

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


基本方法 HashMap
public class Main{
    public static void main(String[] args){
        Map<String, String> map = new HashMap<String, String>();
        //加入元素,加入時如果出現相同的鍵,則新的値會覆蓋原有的鍵對應值,並put方法會返回被覆蓋的値
        map.put("01", "a");
        map.put("02", "b");
        map.put("03", "c");
        System.out.println("containKey: " + map.containsKey("02"));//true
        System.out.println("remove: " + map.remove("03"));//c
        System.out.println(map);//{01=a, 02=b}
        //可以通過get方法的返回值來判斷一個鏈是否存在,通過返回null來判斷
        System.out.println("get: " + map.get("01"));//get: a
        map.put("04", null);
       
        //獲取集合中所有的値
        Collection<String> col = map.values();
        System.out.println(col);// [null, a, b]
    }
}

map集合的兩種取出方式
l   Set<k> keySet(): map中所有的鍵存入到Set集合,因為set具備迭代器,可以用迭代方式取出所有的鍵,在根據get方法,獲取每一個鍵對應的値
l   entrySet(): Set<Map.Entry<k, v>> entrySet map集合中的映射關係存入到了set集合中,而這個關係的數據類型就是Map.Entry

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

使用keySet()
public class Main{
    public static void main(String[] args){
        Map<String, String> map = new HashMap<String, String>();
        map.put("01", "a");
        map.put("02", "b");
        map.put("03", "c");
        //獲取map集合中的所有鍵的Set集合, keySet()
        Set<String> keySet = map.keySet();
        //有了set集合就可以獲取迭代器
        Iterator<String> it = keySet.iterator();
        while(it.hasNext()){
            String key = it.next();
            //有了鍵就可以通過map集合的get方法獲取其對應的値
            String value = map.get(key);
            System.out.println("key: " + key + ", vaule: " + value);
        }//key: 01, vaule: a  //key: 02, vaule: b  //key: 03, vaule: c
    }
}

使用entrySet()
public class Main{
    public static void main(String[] args){
        Map<String, String> map = new HashMap<String, String>();
        map.put("01", "a");
        map.put("02", "b");
        map.put("03", "c");
        //map集合中的映射關係取出,存入到Set集合中
        Set<Map.Entry<String, String>> entrySet = map.entrySet();
       
        Iterator<Map.Entry<String, String>> it = entrySet.iterator();
        while(it.hasNext()){
            Map.Entry<String, String> me = it.next();
            String key = me.getKey();//
            String value = me.getValue();
            System.out.println("key: " + key + ", vaule: " + value);
        }
    }
}

Map.Entry: 其實Entry也是一個介面,他是Map介面中的一個內部介面
ex:
interface Map{
        public static interface Entry{
        public abstract Object getKey();
        public abstract Object getValue();
}
}

class HashMap implements Map{
        class Hash implements Map.Entry{
                public Object getKey();
                public Object getValue();
}
}

Ex:
class Student implements Comparable<Student>{
    private String name;
    private int 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;
    }
   
    public int hashCode(){
        return name.hashCode() + age*34;
    }
   
    public boolean equals(Object obj){
        if(!(obj instanceof Student))
            throw new ClassCastException("不屬於Student");
        Student s = (Student)obj;
        return this.name.equals(s.name) && this.age == s.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 class Main{
    public static void main(String[] args){
        HashMap<Student, String> hm = new HashMap<Student, String>();
        hm.put(new Student("B", 21), "TW");
        hm.put(new Student("A", 18), "HK");
        hm.put(new Student("D", 25), "US");
        hm.put(new Student("C", 30), "JP");
       
        //第一種取出方式 keySet
        Set<Student> keySet = hm.keySet();
        Iterator<Student> it = 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);
        }
    }
}

排序
class Student implements Comparable<Student>{
    private String name;
    private int 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;
    }
   
    public int hashCode(){
        return name.hashCode() + age*34;
    }
   
    public boolean equals(Object obj){
        if(!(obj instanceof Student))
            throw new ClassCastException("不屬於Student");
        Student s = (Student)obj;
        return this.name.equals(s.name) && this.age == s.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 class Main{
    public static void main(String[] args){
        TreeMap<Student, String> tm = new TreeMap<Student, String>(new StuNameComparator());
        tm.put(new Student("B", 21), "TW");
        tm.put(new Student("A", 18), "HK");
        tm.put(new Student("D", 25), "US");
        tm.put(new Student("C", 30), "JP");
       

        Set<Map.Entry<Student, String>> entrySet = tm.entrySet();
        Iterator<Map.Entry<Student, String>> it = entrySet.iterator();
        while(it.hasNext()){
            Map.Entry<Student, String> me = it.next();
            Student stu = me.getKey();
            String addr = me.getValue();
            System.out.println(stu + "... " + addr);
        }
    }
}
//自定義比較器 依姓名排序 在依年齡排序
class StuNameComparator implements Comparator<Student>{
    public int compare(Student s1, Student s2){
        int num = s1.getName().compareTo(s2.getName());
        if(num == 0)
            return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
        return num;
    }
}

獲取字串中的字母出現的次數,產生結果如: a(1), b()3, …
表示每一個字母都有對應的關係,可以選擇map集合,利用其映射關係
當數據之間存在映射關係時,就要先想到map集合

/**
 * 1. 將字串轉成字元陣列
 * 2. 定義map集合,因為結果的字母有順序
 * 3. 將每一個字母作為鍵去查map集合,如果返回null,將該字母和1存入到map集合中
 *    如果返回不是null,說明該字母在map集合已經存在並有對應次數,更新資料
 * 4. map集合中的數據變成指定的字串形式傳回   
 *
 * */
public class Main{
    public static void main(String[] args){
        String result = charCount("aiejoeifcea");
        System.out.println(result);
    }
    public static String charCount(String str){
        char[] chs = str.toCharArray();
        TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
       
        for(int x = 0; x < chs.length ; x++){
            Integer value = tm.get(chs[x]);
            if(value == null){
                tm.put(chs[x], 1);
            }else{
                value = value + 1;
                tm.put(chs[x], value);
            }
        }
        StringBuilder sb = new StringBuilder();
        Set<Map.Entry<Character, Integer>>entrySet = tm.entrySet();
        Iterator<Map.Entry<Character, Integer>> it = entrySet.iterator();
        while(it.hasNext()){
            Map.Entry<Character, Integer> me = it.next();
            Character ch = me.getKey();
            Integer value = me.getValue();
            sb.append(ch + "(" + value + ")");
        }
        return sb.toString();
    }
}

map集合被使用是因為具備映射關係,
public class Main{
    public static void main(String[] args){
        HashMap<String, String> a = new HashMap<String, String>();
        a.put("11", "x1");
        a.put("12", "x2");
       
        HashMap<String, String> b = new HashMap<String, String>();
        b.put("21", "y1");
        b.put("22", "y2");
         
        HashMap<String, HashMap<String, String>> c = new HashMap<String, HashMap<String, String>>();
        c.put("01", a);
        c.put("02", b);
    }
}


Collections
public class Main{
    public static void main(String[] args){
        sortDemo();
    }
    public static void sortDemo(){
        List<String> list = new ArrayList<String>();
        list.add("asc");
        list.add("vdko");
        list.add("aqsqs");
        list.add("zaxce");
        list.add("plldw");
       
        sop(list); //[asc, vdko, aqsqs, zaxce, plldw]
        //Collections.sort(list);
        Collections.sort(list, new StrLenComparator());
        sop(list); //[asc, vdko, aqsqs, plldw, zaxce]
        sop(Collections.max(list)); // zaxce
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

class StrLenComparator implements Comparator<String>{
    public int compare(String s1, String s2){
        if(s1.length() > s2.length()){
            return 1;
        }
        if(s1.length() < s2.length()){
            return -1;
        }
        return s1.compareTo(s2);
    }
}



public class Main{
    public static void main(String[] args){
        sortDemo();
    }
    public static void sortDemo(){
        List<String> list = new ArrayList<String>();
        list.add("c");
        list.add("b");
        list.add("a"); 
       
        Collections.sort(list);
        sop(list);//要先排序 [a, b, c] 否則結果會錯誤
        sop(Collections.binarySearch(list, "b"));//1
        sop(Collections.binarySearch(list, "c"));//2
        sop(Collections.binarySearch(list, "a"));//0

    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}
class StrLenComparator implements Comparator<String>{
    public int compare(String s1, String s2){
        if(s1.length() > s2.length()){
            return 1;
        }
        if(s1.length() < s2.length()){
            return -1;
        }
        return s1.compareTo(s2);
    }
}


class Hello{
    public static void main(String[] args){
        sortDemo();
    }
    public static void sortDemo(){
        List<String> list = new ArrayList<String>();
        list.add("c");
        list.add("b");
        list.add("a"); 
       
        Collections.reverse(list);
        sop(list);//[a, b, c]
        //fill方法可以將list集合中所有元素替換成指定元素
        Collections.fill(list, "123");
        sop(list);//[123, 123, 123]
        Collections.replaceAll(list, "123", "a");
        sop(list);//[a, a, a]
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

Collections.reverseOrder
class Hello{
    public static void main(String[] args){
        Demo();
    }
    public static void Demo(){
        TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder());
        ts.add("a");
        ts.add("b");
        ts.add("c");
        ts.add("d");
        Iterator it = ts.iterator();
        while(it.hasNext()){
            sop(it.next());
        }
    }
    public static void sop(Object obj){
        System.out.println(obj); //d, c, b, a
    }
}

直接使得Collections.reverseOrder將實作的比較類傳入,可直接反轉自定義的排序內容
原本是由字串長度由小到大,反轉後變由大到小
class Hello{
    public static void main(String[] args){
        Demo();
    }
    public static void Demo(){
        TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new StrLenComparator()));
        ts.add("aaaa");
        ts.add("bb");
        ts.add("c");
        ts.add("dddddd");
       
        Iterator it = ts.iterator();
        while(it.hasNext()){
            sop(it.next());
        }
    }
    public static void sop(Object obj){
        System.out.println(obj); //d, c, b, a
    }
}

class StrLenComparator implements Comparator<String>{
    public int compare(String s1, String s2){
        if(s1.length() > s2.length())
            return 1;
        if(s1.length() < s2.length())
            return -1;
        return s1.compareTo(s2);
    }
}

Collections其他方法:
非同步方法轉為同步方法:   static <T>List<T> synchronizedList(List<T> list)
隨機排列方法:   static void shuffle(List<?> list)

Arrays用於操作陣列的工具類,其方法為靜態
ArraysList
class Hello{
    public static void main(String[] args){
        int[] arr = {1, 2, 3};
        sop(Arrays.toString(arr));
       
        //asList將陣列轉為list集合
        //好處為可以使用集合的方法來操作陣列中的元素
        //注意: 將陣列轉為集合後, 不可以使用集合的增刪方法
        //因為陣列的長度是固定, 誤用會發生異常
        String[] arrStr = {"a", "b", "c"};
        List<String> list = Arrays.asList(arrStr);
        sop(list);
       
        int[] nums = {2, 4, 5};
        List<int[]> list2 = Arrays.asList(nums);
        sop(list2);//[[I@af993e]
        //如果陣列中的元素為物件, 那轉為集合後, 陣列中元素可直接轉為集合中的元素
        //如果陣列中的元素為基本數據類型, 那會將該陣列作為集合中的元素存在
        Integer[] nums2 = {1, 2, 3};
        List<Integer> list3 = Arrays.asList(nums2);
        sop(list3);//[1, 2, 3]
       
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

集合轉陣列
class Hello{
    public static void main(String[] args){
        ArrayList<String> al = new ArrayList<String>();
        al.add("a");
        al.add("b");
        al.add("c");
       
        /**
         * 1. 指定類型陣列所需定義的長度?
         * 2. 若定義小於集合的size 則該方法內部會創建一個新的陣列 長度為集合size
         * 3. 若定義大於集合的size 則不會創建新陣列 而是使用傳遞過來的陣列
         * 利用al.size()最正確*/
       
        /**
         * 集合轉陣列原因
         * 為了限定元素的操作 限定增刪操做*/
        String[] arr = al.toArray(new String[0]);
        sop(Arrays.toString(arr));
       
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

foreach
for(數據類型 變量名: 被遍歷集合或陣列)
對集合進行遍歷
只能獲取集合元素,但是不能對集合進行操作

迭代器除了遍歷,還可以進行remove集合中元素的動作
如果用ListIterator,還可以在遍歷過程中對集合進行增刪改查的動作
class Hello{
    public static void main(String[] args){
        ArrayList<String> al = new ArrayList<String>();
        al.add("a");
        al.add("b");
        al.add("c");
       
        for(String s: al){
            //s只能取出 不能修改
            sop(s);
        }
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

JDK1.5版本出現的新特性 可變參數
隱式將這些參數封裝成陣列,一定要定義在參數的最後面
class Hello{
    public static void main(String[] args){
        show(2, 3, 4);
    }
    public static void show(int ...arr){
        System.out.println(arr.length);
    }
}

StaticImport 靜態導入
import java.util.ArrayList;
//靜態導入: 導入的是Arrays這個類中所有靜態成員
import static java.util.Arrays.*;
import static java.lang.System.*;

class Hello{
    public static void main(String[] args){
        int[] arr = {3, 1, 5};
        sort(arr);
        //當類名重名時,需指定具體的包名
        //當方法重名時,指定具備所屬的物件或類
        out.println(Arrays.toString(arr));
    }
}



沒有留言:

張貼留言