黑馬程序員——集合(二)

——- android培訓java培訓、期待與您交流! ———-

泛型

泛型: JDK1.5 版本一會出現的新特性。用於解決安全問題,是一個類型安全機制。

好處:
1,運行時期出現問題ClassCastException,轉移到了編譯時期。
方便於程序員解決問題。也讓運行時期問題減少。
2,避免了強制轉換的麻煩。

泛型格式: 通過<>來定義要操作的引用數據類型。

在使用java提供的對象時,什麼時候寫泛型呢?
通常在集合框架中很常見。
只要見到<>就要定義泛型。

其實<>就是用來接收類型的。
如:ArrayList al = new ArrayList();
當使用集合時,將集合中要存儲的數據類型作爲參數傳遞到<>中即可

代碼示例:

/*
  泛型的使用
*/
import java.util.*;

public class Demo {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<String>();//明確集合的類型是String
        al.add("java01");
        al.add("java");
        al.add("java03sdf");
//      al.add(4);//此處不能執行,在編譯時會出現異常,而不是在運行時纔出現異常。將運行時異常轉移到編譯時異常

        Iterator<String> it = al.iterator();//明確迭代器的類型是String
        while(it.hasNext()){
            String s = it.next();//此處省略了強制轉換,因爲迭代器已經明確了類型是String
            print(s+" : "+s.length());

            /*
             結果:
                java01 : 6
                java : 4
                java03sdf : 9

             */
        }
    }

    public static void print(Object obj) {
        System.out.println(obj);
    }
}
/*
  需求:
    將字符串長度由小到大排序,並且使用泛型的方式
 */
import java.util.*;

public class Demo {
    public static void main(String[] args) {
        TreeSet<String> al = new TreeSet<String>(new MyComparator());

        //此方式是錯的,ArrayList構造方法不能接收MyComparator對象
        //ArrayList<String> al = new ArrayList<String>(new MyComparator());

        al.add("sfdgsdfsfgg");
        al.add("fgsdfgfg");
        al.add("asfga");
        al.add("asfkk");

        Iterator<String> it = al.iterator();
        while(it.hasNext()){
            print(it.next());

            /*
             結果:
                asfga
                asfkk
                fgsdfgfg
                sfdgsdfsfgg
             */
        }
    }

    public static void print(Object obj) {
        System.out.println(obj);
    }
}
class MyComparator implements Comparator<String>{//Comparator也是泛型
    public int compare(String o1, String o2) {//注意,此處不是public int compare(Object o1, Object o2) 
        int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));
        if(num == 0)
            return o1.compareTo(o2);
        return num;
    }
}

泛型類

代碼示例:

/*
  泛型類。

  什麼時候使用泛型類?
    當類中要操作的引用數據類型不確定的時候。
    在早期定義Object來操作不確定的引用數據類型完成擴展。
    現在定義泛型來完成擴展。

    在類中的方法操作的都是同一種類型時,那麼可以將類定義爲泛型類。如ArrayList集合中的方法,操作的都是同一種類型
 */
import java.util.*;

class Student{

}
class Worker{

}
//將此類定義爲泛型類
class Tool<T>{
    private T t;
    public void setObject(T t){
        this.t = t;
    }
    public Object getObject(){
        System.out.println("獲取到了");
        return t;
    }
}
public class Demo {
    public static void main(String[] args) {
        Tool<Student> t = new Tool<Student>();
        t.setObject(new Student());
//      t.setObject(new Worker());//此方法編譯時異常,因爲Tool類型Student,當傳入Worker類型時編譯會出現異常
        Student s = (Student) t.getObject();
    }
}

泛型類的侷限性

代碼示例:

/*
 * 演示泛型類的侷限性
 *
 * 泛型類定義的泛型,在整個類中有效。如果泛型類的對象明確要操作的具體類型後,
 * 所有要操作的類型就已經固定了。
 */
import java.util.*;
class Person<T>{
    public void function(T t){
        System.out.println("function:"+t);
    }
    public void method(T t){
        System.out.println("method:"+t);
    }
}
public class Demo {
    public static void main(String[] args) {
        Person<String> p1 = new Person<String>();//定義泛型爲String,那麼方法中的參數,都已經固定爲String了
        p1.function("haha");
//      p1.method(4);//此處編譯失敗,因爲p1這個對象指定的類型爲String,則裏邊的方法接收的參數也爲String。如: p1這個對象中的方法爲 public void function(String t){},這是侷限性
        Person<Integer> p2 = new Person<Integer>();
        p2.method(4);
//      p2.function("haha");//編譯失敗,因爲p2指定的類型爲Integer,裏邊的方法接收的參數爲Integer. 如:public void method(Integer t){},這是侷限性
    }
}

泛型方法

代碼示例:

/*
 * 爲了讓不同方法可以操作不同類型,而且類型還不確定。
 * 那麼可以將泛型定義在方法上。
 */
import java.util.*;
class Person{
    public <T> void function(T t){
        System.out.println("function:"+t);
    }
    public <T> void method(T t){
        System.out.println("method:"+t);
    }
}
public class Demo {
    public static void main(String[] args) {
        Person p = new Person();
        p.function("haha");//不會編譯錯誤。因爲此方法爲泛型方法。
                    //相當於public void function(String t){}
        p.method(5);//不會編譯錯誤。因爲此方法爲泛型方法。
                    //相當於public void method(Integer t){}

    }
}

靜態泛型方法代碼示例:

/*
 * 特殊之處:
 *      靜態方法不可以訪問類上定義的泛型。
 *      如果靜態方法操作的應用數據類型不確定,可以將泛型定義在靜態方法上
 * 
 * 注意:泛型只能接受對象。如:
 *      public <T> void method(T t){
 *          System.out.println("method:"+t);
 *      }
 *      當傳入一個正數5時,系統則執行自動裝箱,泛型 T 的類型爲Integer而不是int
 */
import java.util.*;
class Person<T>{
    public void function(T t){
        System.out.println("function:"+t);
    }
    public <T> void method(T t){
        System.out.println("method:"+t);
    }
//  public static void print(T t){//此方法不能執行,靜態方法不可以訪問類上的泛型,因爲類上的泛型是隨着對象的創建而加載的,而靜態方法隨着類加載,靜態方法加載的比對象快
//  }
    public static <W> void print(W w){//此方法可以執行,因爲是靜態泛型方法
        System.out.println("print:"+w);
    }
}
public class Demo {
    public static void main(String[] args) {
        Person<String> p = new Person<String>();
        p.function("haha");
        //p.function(4);//編譯失敗,因爲此方法爲public void function(String t){}

        p.method("hehe");//此方法沒有錯誤,因爲是泛型類。public void method(String t){}
        p.method(6);//此方法沒有錯誤,因爲是泛型類。public void method(Integer t){}

        Person.print("haha");
        Person.print(5);
    }
}

泛型接口

代碼示例:

/*
 * 泛型接口
 * 
 * 開發中一般不多見
 */
import java.util.*;
interface Inter<T>{
    void show(T t);
}
class Person<T> implements Inter<T>{//此處定義了泛型T,那麼Person也要定義爲泛型T,同時實現Inter的方法參數也爲T
    public void show(T t) {
        System.out.println("Person show:"+t);
    }
}
class Student implements Inter<String>{//若此處定義了泛型類型爲String類型,則Student類不用定義爲泛型,同時實現Inter的方法參數爲String。
    public void show(String t) {//因爲接口泛型定義爲String,那麼此方法要能接收String類型的參數
        System.out.println("Student show"+t);
    }
}
public class Demo {
    public static void main(String[] args) {
        Person<Integer> p = new Person<Integer>();
        p.show(4);
//      p.show("haha");//編譯失敗,因爲Person指定爲Integer

        Student s = new Student();
        s.show("haha");
    }
}

通配符 ?(佔位符)的使用

代碼示例:

/*
  通配符的使用方式
*/
import java.util.*;
public class Demo {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<String>();
        al.add("java01");
        al.add("java02");
        al.add("java03");
        print(al);

        ArrayList<Integer> al1 = new ArrayList<Integer>();
        al1.add(4);
        al1.add(5);
        al1.add(6);
        print(al1);
    }
    public static void print(ArrayList<?> al){//ArrayList<?> al = new ArrayList<Integer>();,此處可以接收多種類型的ArrayList。
                        //如:ArrayList<?> al = new ArrayList<String>();此類型也可以接收
        Iterator<?> it = al.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
            //System.out.println(it.next().length());//此方法不可以使用,因爲接收的類型不確定,length()是針對於字符串類型使用的
            /*
             結果:
                java01
                java02
                java03
                4
                5
                6
             */
        }
    }
}

泛型限定

泛型的限定。
? extends E:可以接收E類型或者E的子類型。 上限限定。
? super E:可以接收E類型或者E的父類型。 下限限定。

注意:

ArrayList<String> al = new ArrayList<Integer>();
這種方式是不允許的,因爲泛型必須要保證左邊等於右邊。如:ArrayList<String> al = new ArrayList<String>();

代碼示例:

/*
   泛型的上限演示:  ? extends E
*/
import java.util.*;
class Person{
    private String name;
    public Person(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}
class Student extends Person{
    public Student(String name) {
        super(name);
    }
}
public class Demo {
    public static void main(String[] args) {
        ArrayList<Person> al = new ArrayList<Person>();
        al.add(new Person("java01"));
        al.add(new Person("java02"));
        al.add(new Person("java03"));
        print(al);

        ArrayList<Student> al1 = new ArrayList<Student>();
        al1.add(new Student("java001"));
        al1.add(new Student("java002"));
        al1.add(new Student("java003"));
        //print(al1);//此處編譯失敗。相當於ArrayList<Person> al = new ArrayList<Student>()。
                //必須保證左右兩邊相等才行,如ArrayList<Student> al = new ArrayList<Student>();
    }
    public static void print(ArrayList<Person> al){//該方法的參數ArrayList<Person> al 只能接收Person類型
        Iterator<Person> it = al.iterator();
        while(it.hasNext()){
            System.out.println(it.next().getName());
            /*
             結果:
                java01
                java02
                java03
             */
        }
    }
}

將以上代碼修改爲通用的代碼如下:

/*
   泛型的上限演示:  ? extends E
*/
import java.util.*;
class Person{
    private String name;
    public Person(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}
class Student extends Person{
    public Student(String name) {
        super(name);
    }
}
public class Demo {
    public static void main(String[] args) {
        ArrayList<Person> al = new ArrayList<Person>();
        al.add(new Person("java01"));
        al.add(new Person("java02"));
        al.add(new Person("java03"));
        print(al);

        ArrayList<Student> al1 = new ArrayList<Student>();
        al1.add(new Student("java001"));
        al1.add(new Student("java002"));
        al1.add(new Student("java003"));
        print(al1);
    }
    public static void print(ArrayList<? extends Person> al){//該方法的參數ArrayList<? extends Person> al  代表可以接收Person或者Person的子類型
        Iterator<? extends Person> it = al.iterator();
        while(it.hasNext()){
            System.out.println(it.next().getName());//調用了父類中的getName方法。如果集合接受的是子類,子類也可以調用此方法
            /*
             結果:
                java01
                java02
                java03
                java001
                java002
                java003
             */
        }
    }
}
/*
   泛型的下限演示:  ? super E
*/
import java.util.*;

class Person {//定義一個人
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

class Student extends Person {//學生繼承了人
    public Student(String name) {
        super(name);
    }
}

class Worker extends Person {//工人也繼承人
    public Worker(String name) {
        super(name);
    }
}

class WorkerComp implements Comparator<Worker>{//定義一個 專門比較工人 的比較器,將工人進行排序
    public int compare(Worker o1, Worker o2) {
        return o2.getName().compareTo(o1.getName());//倒序排序
    }
}
class StuComp implements Comparator<Student>{//定義一個 專門比較學生 的比較器,將學生進行排序
    public int compare(Student o1,Student o2){
        return o2.getName().compareTo(o1.getName());//倒序排序
    }
}
public class Demo {
    public static void main(String[] args) {
        TreeSet<Worker> ts = new TreeSet<Worker>(new WorkerComp());//將工人比較器傳入工人集合的構造方法
        //TreeSet<Worker> t = new TreeSet<Worker>(new StuComp());//此方法不能執行,構造方法爲:new TreeSet<Worker>(Comparator<? super Werker>),該構造方法只能接受Werker或者Werker的父類
        ts.add(new Worker("worker01"));
        ts.add(new Worker("worker02"));
        ts.add(new Worker("worker03"));
        Iterator<Worker> it = ts.iterator();
        while(it.hasNext())
            System.out.println(it.next().getName());
        /*
         結果:
            worker03
            worker02
            worker01
         */

        TreeSet<Student> ts1 = new TreeSet<Student>(new StuComp());//將學生比較器傳入學生集合的構造方法
        //TreeSet<Student> t1 = new TreeSet<Student>(new WorkerComp());//此方法不能執行,構造方法爲:new TreeSet<Student>(Comparator<? super Student>),該構造方法只能接受Student或者Student的父類
        ts1.add(new Student("student01"));
        ts1.add(new Student("student02"));
        ts1.add(new Student("student03"));
        Iterator<Student> it1 = ts1.iterator(); 
        while(it1.hasNext()){
            System.out.println(it1.next().getName());
            /*
             結果:
                student03
                student02
                student01
             */
        }
    }
}

修改上邊的代碼,新的代碼如下

/*
   泛型的下限演示:  ? super E
*/

import java.util.*;

class Person {//人
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

class Student extends Person {//學生繼承人
    public Student(String name) {
        super(name);
    }
}

class Worker extends Person {//工人繼承人
    public Worker(String name) {
        super(name);
    }
}

class Comp implements Comparator<Person>{//此處可以接收Person的子類
    public int compare(Person o1, Person o2) {
        return o2.getName().compareTo(o1.getName());//倒序排序
    }
}

public class Demo {
    public static void main(String[] args) {
        TreeSet<Worker> ts = new TreeSet<Worker>(new Comp());//將 人 的比較器傳入 工人 的構造方法。 new TreeSet<Worker>(Comparator<? super Worker>),可以接收Worker或者Worker的父類型
        ts.add(new Worker("worker01"));
        ts.add(new Worker("worker02"));
        ts.add(new Worker("worker03"));
        Iterator<Worker> it = ts.iterator();
        while(it.hasNext())
            System.out.println(it.next().getName());
        /*
         結果:
            worker03
            worker02
            worker01
         */

        TreeSet<Student> ts1 = new TreeSet<Student>(new Comp());//將 人 的比較器傳入 學生 的構造方法。 new TreeSet<Student>(Comparator<? super Student>),可以接收Student或者Student的父類型
        ts1.add(new Student("student01"));
        ts1.add(new Student("student02"));
        ts1.add(new Student("student03"));
        Iterator<Student> it1 = ts1.iterator(); 
        while(it1.hasNext()){
            System.out.println(it1.next().getName());
            /*
             結果:
                student03
                student02
                student01
             */
        }
    }
}

Map集合

Map集合: 該集合存儲鍵值對。一對一對往裏存。而且要保證鍵的唯一性。

    1,添加
        <V> value = map.put(K key,V value);         返回被覆蓋的value值,如果沒有被覆蓋,返回null
        putAll(Map<? extends K,? extends V> m);
    2,刪除    
        clear();                        清空集合
        <V> value = map.remove(Object key);         刪除某個鍵
    3,判斷
        boolean b = map.containsValue(Object value);        判斷map集合是否包含值
        boolean b = map.containsKey(Object key);        判斷map集合是否包含鍵
        boolean b = map.isEmpty();              判斷集合是否爲空
    4,獲取
        <V> value = map.get(Object key);            獲取某個鍵中的值
        int l = map.size();                 獲取集合中元素個數
        Collection<V> coll = map.values();          獲取集合中所有的值

        Set<Map.Entry<K,V>> entrySet = map.entrySet();      獲取Map集合中的映射關係,存入到Set集合中
        Set<K> keySet = map.keySet();               獲取鍵,將鍵存入Set集合中

|--Map

    |--Hashtable:底層是哈希表數據結構,不可以存入null鍵和null值。
                JDK1.0版本出現,效率低。該集合是線程同步的
    |--HashMap:底層是哈希表數據結構,允許使用null值和null鍵。將Hashable代替。
                  JDK1.2版本出現,效率高,該集合是不同步的
    |--TrreMap:底層是二叉樹數據結構。可以用於給map集合中的鍵進行排序。線程不同步

Map和Set集合很像,其實,Set底層就是使用了Map集合

代碼示例:

/*
  Map集合中的方法演示
*/
import java.util.*;
public class Demo {

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

        //添加。如果添加時,出現相同的鍵。那麼後添加的值會覆蓋原有鍵對應的值。
        //並且put方法會返回被覆蓋的值。
        print(map.put("01", "zhangsan1"));//結果:null
        print(map.put("01", "lisi"));//結果:zhangsan1。因爲鍵相同,
                                    //後添加的值覆蓋原有的值,put方法返回被覆蓋的值
        map.put("02", "zhangsan2");
        map.put("03", "zhangsan3");
        map.put("04", "zhangsan4"); 
        map.put("05", null);// HashMap支持null鍵和null值
        print(map);//結果:{04=zhangsan4, 05=null, 01=lisi, 02=zhangsan2, 03=zhangsan3},輸出結果是無序的,因爲HashMap底層數據結構是哈希表

        //刪除
        map.remove("02");
        print(map);//結果:{04=zhangsan4, 05=null, 01=lisi, 03=zhangsan3}

        //判斷
        print(map.containsKey("03"));//結果:true。可以判斷集合map中是否包含鍵03

        //獲取
        print(map.get("02"));//結果:null。可以用get方法判斷集合中是否包含元素,如果返回值爲null,則不包含
        //print(map.get("03"));//結果:zhangsan3。可以用get方法判斷集合中是否包含元素,如果返回值爲null,則不包含

        Collection<String> coll = map.values();
        print(coll);//結果:[zhangsan4, null, lisi, zhangsan3]
    }
    public static void print(Object obj){
        System.out.println(obj);
    }
}

Map集合的第一種取出方式(KeySet方法)

代碼示例:

/*
    keySet方法的使用

    Set<K> KeySet:將map中所有的鍵存入到Set集合。因爲Set集合具備迭代器。
    所以可以用迭代器的方式取出所有的鍵,再根據get方法,獲取每一個鍵對應的值

    Map集合取出原理:將Map集合轉成Set集合,再通過迭代器取出。
*/
import java.util.*;
public class Demo {

    public static void main(String[] args) {
        Map<String,String> map = new HashMap<String,String>();
        map.put("01", "zhangsan1");
        map.put("02", "zhangsan2");
        map.put("03", "zhangsan3");
        map.put("04", "zhangsan4");

        Set<String> keySet =  map.keySet();//先獲取map集合中所有鍵的Set集合

        Iterator<String> it = keySet.iterator();//有了Set集合。就可以獲取其迭代器
        while(it.hasNext()){
            String key = it.next();//迭代器中的類型屬於String
            String value = map.get(key);//有了鍵,就可以通過Map集合的get方法獲取其對應的值
            print("key:"+key+" value:"+value);

            /*
             結果:
                key:04 value:zhangsan4
                key:01 value:zhangsan1
                key:02 value:zhangsan2
                key:03 value:zhangsan3
             */
        }
    }
    public static void print(Object obj){
        System.out.println(obj);
    }
}

Map集合的第二種取出方式(entrySet方法)

代碼示例:

/*
    entrySet方法的使用

    Set<Map.Entry<K,V> entrySet: 將map集合中的映射關係存入到集合中,
    而這個關係的數據類型就是:Map.Entry
*/
import java.util.*;
public class Demo {

    public static void main(String[] args) {
        Map<String,String> map = new HashMap<String, String>();
        map.put("01", "zs1");
        map.put("02", "zs2");
        map.put("03", "zs3");
        map.put("04", "zs4");

        //將Map集合中的映射關係取出,存入到Set集合中
        Set<Map.Entry<String, String>> entrySet = map.entrySet();

        //有了Set集合。就可以獲取其迭代器
        Iterator<Map.Entry<String, String>> it = entrySet.iterator();

        while(it.hasNext()){
            Map.Entry<String, String> me = it.next();//迭代器中的類型屬於Map.Entry<String, String>
            String key = me.getKey();//Map.Entry<String, String>中的key類型屬於String
            String value = me.getValue();//Map.Entry<String, String>中的key類型屬於String
            print(key+".."+value);
        }
    }
    public static void print(Object obj){
        System.out.println(obj);
    }
}

Map集合的練習

/*
 * 每一個學生都有對應的歸屬地。
 * 學生Student,地址String.
 * 學生屬性:姓名,年齡。
 * 注意:姓名和年齡相同視爲同一個學生。
 * 保證學生的唯一性。
 * 
 * 1,描述學生。
 * 2,定義map容器。將學生作爲鍵,地址作爲值。存入。
 * 3,獲取map集合中的元素。
 */
import java.util.*;

class Student implements Comparable<Student>{
    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 hashCode() {//覆蓋hashCode方法,爲了保證唯一性
        return name.hashCode() + age*15;
    }

    public boolean equals(Object obj) {//覆蓋equals方法,爲了保證唯一性
        if (!(obj instanceof Student))
            throw new ClassCastException("類型不匹配");
        Student stu = (Student) obj;
        return this.name.equals(stu.getName()) && this.age==stu.getAge();
    }

    public int compareTo(Student s) {//實現compareTo方法,使數據按照姓名排序
        int num = this.name.compareTo(s.getName());
        if(num == 0){
            return new Integer(this.age).compareTo(new Integer(s.getAge()));
        }
        return num;
    }

}

public class Demo {
    public static void main(String[] args) {
        HashMap<Student, String> hs = new HashMap<Student, String>();
        hs.put(new Student("zhangsan", 20), "北京");
        hs.put(new Student("zhangsan", 20), "北京");
        hs.put(new Student("lisi", 25), "北京");
        hs.put(new Student("wangwu", 30), "天津");
        //第一種獲取方式
        Set<Student> keySet = hs.keySet();//先獲取map集合中所有鍵的Set集合
        Iterator<Student> it = keySet.iterator();//有了Set集合。就可以獲取其迭代器
        while(it.hasNext()){
            Student key = it.next();//獲取鍵
            String value = hs.get(key);//獲取鍵的值
            print("name=" + key.getName() + "...age=" + key.getAge() + "...地址="+ value);
            /*
             結果:
             name=lisi...age=25...地址=北京
            name=zhangsan...age=20...地址=北京
            name=wangwu...age=30...地址=天津
             */

        }

        //第二種獲取方式
        Set<Map.Entry<Student, String>> entrySet = hs.entrySet();//將Map集合中的映射關係取出,存入到Set集合中
        Iterator<Map.Entry<Student, String>> it1 = entrySet.iterator();//有了Set集合。就可以獲取其迭代器
        while (it1.hasNext()) {
            Map.Entry<Student, String> me = it1.next();//迭代器中的類型屬於Map.Entry<String, String>
            Student stu = me.getKey();//獲取鍵
            String s = me.getValue();//獲取值
            print("name=" + stu.getName() + "........age=" + stu.getAge() + "........地址="+ s);
            /*
              結果: 
                name=lisi........age=25........地址=北京
                name=zhangsan........age=20........地址=北京
                name=wangwu........age=30........地址=天津
             */
        }
    }

    public static void print(Object obj) {
        System.out.println(obj);
    }
}
/*
 * 每一個學生都有對應的歸屬地。
 * 學生Student,地址String.
 * 學生屬性:姓名,年齡。
 * 注意:姓名和年齡相同視爲同一個學生。
 * 保證學生的唯一性。
 * 
 * 
 * 需求:對學生對象的 年齡 進行升序排序。
 * 
 * 因爲數據是以鍵值對形式存在的。
 * 所以要使用可以排序的Map集合。TreeMap
 */
import java.util.*;
class Student implements Comparable<Student>{
    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 hashCode(){//覆蓋hashCode方法,爲了保證唯一性
        return name.hashCode() + age*18;
    }
    public boolean equals(Object obj){//覆蓋equals方法,爲了保證唯一性
        if(!(obj instanceof Student))
            throw new ClassCastException("類型轉換異常");
        Student stu = (Student)obj;
        return this.name.equals(stu.getName()) && this.age == stu.getAge();
    }
    public int compareTo(Student stu){//實現compareTo方法,使數據按照姓名排序
        int num = name.compareTo(stu.getName());
        if(num == 0)
            return new Integer(age).compareTo(new Integer(stu.getAge()));
        return num;
    }
}

//定義一個比較器,使學生按照年齡排序
class StuAgeComparator implements Comparator<Student>{
    public int compare(Student s1,Student s2){
        int num = new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
        if(num == 0)
            return s1.getName().compareTo(s2.getName());
        return num;
    }
}
public class Demo {
    public static void main(String[] args) {
        TreeMap<Student, String> tm = new TreeMap<Student,String>(new StuAgeComparator());
        tm.put(new Student("zhangsan", 20), "天津");
        tm.put(new Student("zhangsan", 20), "北京");
        tm.put(new Student("lisi", 25), "北京");
        tm.put(new Student("wangwu", 30), "天津");

        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 s = me.getValue();
            print("name:"+stu.getName()+"...age:"+stu.getAge()+"...name:"+s);
            /*
             結果:
                name:zhangsan...age:20...name:北京
                name:lisi...age:25...name:北京
                name:wangwu...age:30...name:天津
             */
        }
    }

    public static void print(Object obj) {
        System.out.println(obj);
    }
}
/*
 * 練習:
 * "abcdeabcab"獲取字符串中的字符出現次數。
 * 
 * 希望打印結果:a(3)b(3)c(2)....
 * 
 * 通過結果發現,每一個字母都有對應的次數,
 * 說明字符和次數之間都有映射關係。
 * 
 * 注意:當發現有映射關係時,可以選擇Map集合。因爲Map集合中存放的就是映射關係。
 * 
 * 說明時候使用Map集合呢?
 * 當數據之間存在映射關係時,就要現象Map集合。
 * 
 * 思路:
 * 1,將字符串轉換成字符數組。因爲要對每一個字母進行操作。
 * 2,定義一個Map集合,因爲打印結果有序,所以使用TreeMap集合。
 * 3,遍歷字符數組。
 *      將每一個字母作爲鍵去查Map集合。
 *      如果返回null,將該字母和1存入到Map集合中。
 *      如果返回不爲null,說明該字符在集合中已經存在,並有對應的次數。
 *      那麼就獲取該次數並進行自增,然後將該字母和自增後的次數存入到Map集合中,並覆蓋掉原來鍵所對應的值   。
 * 4,將Map集合中的數據變成指定的字符串返回。
 */
import java.util.*;
public class Demo {
    public static void main(String[] args) {
        String s = charCount("abcdeabcab");
        System.out.println(s);//結果:a(3)b(3)c(2)d(1)e(1)
    }

    public static String charCount(String s) {
        StringBuilder sb = new StringBuilder();
        char[] chs = s.toCharArray();
        TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();//創建一個TreeMap集合
        for(int i=0;i<chs.length;i++){
            Integer value = tm.get(chs[i]);//獲取鍵值
            if(value == null){
                tm.put(chs[i], 1);
            }
            else{
                value = value+1;
                tm.put(chs[i], value);
            }
        }
        Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();//將TreeMap的映射存入到Set集合中
        Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator();//有了Set集合。就可以獲取其迭代器
        while(it.hasNext()){
            Map.Entry<Character,Integer> me = it.next();//迭代器中的類型屬於Map.Entry<String, String>
            sb.append(me.getKey()+"("+me.getValue()+")");
        }
        return sb.toString();
    }
}

Map集合的擴展知識

/*
 * Map擴展知識。
 * 
 * Map集合被使用時因爲具備映射關係。
 * 
 * "yureban" "01" "zhangsan";
 * "yuerban" "02" "lisi";
 * "jiuyeban" "01" "wangwu";
 * "jiuyeban" "02" "zhaoliu";
 * 
 * 一個學校有 名字和多個教室,每個教室都有 學號和學生。
 * 如:一個學校名字爲czbk,並且有yureban和jiuyeban。yureban中有
 * 多個學號和姓  名。jiuyeban中有 多個學號和姓名
 */
import java.util.*;
public class Demo {
    public static void main(String[] args) {
        //創建一個學校,學校中可以存放   教室名和教室中的內容
        HashMap<String, HashMap<String, String>> czbk = new HashMap<String, HashMap<String,String>>();
        //創建預熱班教室,教室中可以存放   學號和姓名
        HashMap<String,String> yure = new HashMap<String, String>();
        //創建就業班教室,教室中可以存放   學號和姓名
        HashMap<String,String> jiuye = new HashMap<String, String>();

        czbk.put("yureban", yure);
        czbk.put("jiuyeban", jiuye);

        yure.put("01", "zhangsan");
        yure.put("02", "lisi");

        jiuye.put("01", "wangwu");
        jiuye.put("02", "zhaoliu");

        //遍歷czbk集合。獲取所有教室
        Iterator<String> it = czbk.keySet().iterator();
        while(it.hasNext()){
            String key = it.next();
            HashMap<String, String> value = czbk.get(key);
            print(key);
            printHashMap(value);
        }
    }
    public static void printHashMap(HashMap<String, String> hm){
        Set<Map.Entry<String, String>> entrySet = hm.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();
            print("xuehao:"+key+"....name:"+value);
            /*
             結果:
                jiuyeban
                xuehao:01....name:wangwu
                xuehao:02....name:zhaoliu
                yureban
                xuehao:01....name:zhangsan
                xuehao:02....name:lisi
             */
        }
    }
    public static void print(Object obj){
        System.out.println(obj);
    }
}
/*
 * Map擴展知識。
 * 
 * Map集合被使用時因爲具備映射關係。
 * 
 * "yureban" Student("01" "zhangsan");
 * "yuerban" Student("02" "lisi");
 * "jiuyeban" Student("01" "wangwu");
 * "jiuyeban" Student("02" "zhaoliu");
 * 
 * 一個學校有多個教室,每個教室都有學號和姓名,把每個教室中的學號和姓名封裝成對象。
 * 這種映射關係使用HashMap<String, ArrayList<Student>>
 * 在開發中這種用法比較常見
 */
import java.util.*;
import java.util.Map.Entry;
class Student{
    String name;
    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 String toString(){
        return name + "....." + age;
    }
}
public class Demo {
    public static void main(String[] args) {
        //創建一個學校,學校中可以存放   教室名和學生對象。
        HashMap<String, List<Student>> czbk = new HashMap<String, List<Student>>();

        //創建一個 預熱班 的學生集合
        ArrayList<Student> yure = new ArrayList<Student>();

        //創建一個 就業班 的學生集合
        ArrayList<Student> jiuye = new ArrayList<Student>();

        //將 預熱班 學生的集合添加到 預熱班 中
        czbk.put("yureban", yure);

        //將 就業班 學生的集合添加到 就業班 中
        czbk.put("jiuyeban", jiuye);

        yure.add(new Student("zhangsan01",20));//在預熱班中添加一個學生對象
        yure.add(new Student("zhangsan02",30));//在預熱班中添加一個學生對象

        jiuye.add(new Student("lisi01",20));//在就業班中添加一個學生對象
        jiuye.add(new Student("lisi02",30));//在就業班中添加一個學生對象

        Iterator<Map.Entry<String, List<Student>>> it = czbk.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry<String, List<Student>> me = it.next();
            String key = me.getKey();
            List<Student> value = me.getValue();
            print(key);
            printArrayList(value);
            /*
             結果:
                jiuyeban
                lisi01.....20
                lisi02.....30
                yureban
                zhangsan01.....20
                zhangsan02.....30
             */
        }
    }
    public static void printArrayList(List<Student> al){
        Iterator<Student> it = al.iterator();
        while(it.hasNext()){
            Student stu = it.next();
            print(stu);     //相當於print(stu.toString());
        }
    }
    public static void print(Object obj){
        System.out.println(obj);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章