Java學習總結(六)——(Map集合,Comparator接口,異常等)

一.Comparator接口java

*Comparator接口的使用程序員

(1)使用Comparable接口定義排序順序有侷限性:實現此接口的類只能按compareTo()定義的這一種方式排序。編程

(2)若是同一類對象要有多種排序方式,應該爲該類定義不一樣的比較器(實現Comparator接口的類)TreeSet有一個構造方法容許給定比較器,它就會根據給定的比較器對元素進行排序.數組

(3)Comparator接口中的比較方法多線程

示例:public int compare(Object o1, Object o2); app

     該方法若是ide

     返回 0,表示 o1 == o2測試

     返回正數,表示 o1 > o2ui

     返回負數,表示 o1 < o2this

例(以學生成績排名爲例):

學生類(Student):

package comparator;

 

public class Student {

    private String name;

    private int score;//總分

    private int math;//語文成績

    public Student() {

    super();

    }

    public Student(String name, int score, int math) {

        super();

        this.name = name;

        this.score = score;

        this.math = math;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }    

    public int getScore() {

        return score;

    }

    public void setScore(int score) {

        this.score = score;

    }

    public int getMath() {

        return math;

    }

    public void setMath(int math) {

        this.math = math;

    }

    @Override

    public String toString() {

        return "Student [name=" + name + ", score=" + score + ", math=" + math

        + "]";

    }

 

}

以總分爲第一排序準則類(ScoreRule):

package comparator;

 

import java.util.*;

 

    public class ScoreRule implements Comparator<Student> {

 

    @Override

    public int compare(Student stu1, Student stu2) {

        if(stu1.getScore()>stu2.getScore()){

            return -1;

        }else if(stu1.getScore()<stu2.getScore()){

            return 1;

        }else{

        if(stu1.getMath()>stu2.getMath()){

            return -1;

        }else if(stu1.getMath()<stu2.getMath()){

            return 1;

        }else{

            return stu1.getName().compareTo(stu2.getName());

            }

        }

 

    }

 

}

以數學成績爲第一標準排序類(MathRule):

package comparator;

 

import java.util.Comparator;

 

    public class MathRule implements Comparator<Student>{

 

    @Override

    public int compare(Student stu1, Student stu2) {

        if(stu1.getMath()>stu2.getMath()){

            return -1;

        }else if(stu1.getMath()<stu2.getMath()){

            return 1;

        }else{

        if(stu1.getScore()>stu2.getScore()){

            return  -1;

        }else if(stu1.getScore()<stu2.getScore()){

            return 1;

        }else{

            return stu1.getName().compareTo(stu2.getName());

        }

    }

}

 

}

測試TreeSet類:

package comparator;

 

import java.util.TreeSet;

 

public class TestSetDemo {

 

    public static void main(String[] args) {

        TreeSet<Student> set=new TreeSet<Student>(new ScoreRule());

        set.add(new Student("獨孤求敗",786,145));

        set.add(new Student("王磊",456,78));

                        set.add(new Student("王忠磊",564,97));

                        set.add(new Student("風清揚",786,123));

                        set.add(new Student("王磊",456,78));

                        set.add(new Student("王磊",456,78));

                        set.add(new Student("楊過",456,98));

                        set.add(new Student("令狐沖",556,86));

                        set.add(new Student("張無忌",665,100));

                        set.add(new Student("獨孤求敗",786,145));

                        set.add(new Student("孫悟空",754,147));

                        set.add(new Student("唐僧",453,67));

                        System.out.println("以總分爲 排序第一標準:");

        for(Student stu:set){

            System.out.println(stu);

        }

        System.out.println();

                    TreeSet<Student> set1=new TreeSet<Student>(new MathRule());

                    set1.add(new Student("獨孤求敗",786,145));

                    set1.add(new Student("王磊",456,78));

                    set1.add(new Student("王忠磊",564,97));

                    set1.add(new Student("風清揚",786,123));

                    set1.add(new Student("王磊",456,78));

                    set1.add(new Student("王磊",456,78));

                    set1.add(new Student("楊過",456,98));

                    set1.add(new Student("令狐沖",556,86));

                    set1.add(new Student("張無忌",665,100));

                    set1.add(new Student("獨孤求敗",786,145));

                    set1.add(new Student("孫悟空",754,147));

                    set1.add(new Student("唐僧",453,67));

                    System.out.println("以數學成績爲第一排序標準:");

                    for(Student stu:set1){

                                System.out.println(stu);

                            }

                        }

                     

                    }

                    運行結果爲:

                    以總分爲 排序第一標準:

                    Student [name=獨孤求敗, score=786, math=145]

                    Student [name=風清揚, score=786, math=123]

                    Student [name=孫悟空, score=754, math=147]

                    Student [name=張無忌, score=665, math=100]

                    Student [name=王忠磊, score=564, math=97]

                    Student [name=令狐沖, score=556, math=86]

                    Student [name=楊過, score=456, math=98]

                    Student [name=王磊, score=456, math=78]

                    Student [name=唐僧, score=453, math=67]

                     

                    以數學成績爲第一排序標準:

                    Student [name=孫悟空, score=754, math=147]

                    Student [name=獨孤求敗, score=786, math=145]

                    Student [name=風清揚, score=786, math=123]

                    Student [name=張無忌, score=665, math=100]

                    Student [name=楊過, score=456, math=98]

                    Student [name=王忠磊, score=564, math=97]

                    Student [name=令狐沖, score=556, math=86]

                    Student [name=王磊, score=456, math=78]

                    Student [name=唐僧, score=453, math=67]

分析:例中分別以學生的總分和數學分數爲第一標準進行了排序,屬於同一對象多種排序,故咱們實現了Comparator接口實現了接口中的public int compare(Object o1, Object o2)方法,分別制定了各類排序得規則(即比較器),TreeSet中的構造方法容許給定比較器,按照比較器進行排序。

二.Map集合

1.特色:

1)實現Map接口的集合類用來存儲「鍵-值」映射對。

2)不能包含重複的鍵,每一個鍵最多隻能映射到一個值,值能夠重複。

3JDK APIMap接口的實現類經常使用的有:

    HashMap

    TreeMap

    Hashtable (不經常使用)

    Properties

2.Map接口中的經常使用方法:

(1)Object  put(Object key, Object value); //將指定的「鍵-值」對存入Map

(2)Object  get(Object key);  //返回指定鍵所映射的值

(3)Object  remove(Object key); //根據指定的鍵把此「鍵-值」對從Map中移除。

(4)boolean  containsKey(Object key);   //判斷此Map是否包含指定鍵的「鍵-值」對。

(5)boolean  containsValue(Object value);     //判斷此Map是否包含指定值的「鍵-值」對。

(6)boolean  isEmpty();  //判斷此Map中是否有元素。

(7)int  size();   //得到些Map中「鍵-值」對的數量。

(8)void  clear();   //清空Map中的全部「鍵-值」對。

(9)Set  keySet();    //返回此Map中包含的鍵的Set集。

(10)Collection values();   //返回此Map中包含的值的Collection集。

(11)Set<Map.Entry<K,V>> entrySet() 將全部包含鍵-值對的Map.Entry收集到Set

3.Map.Entry接口:

*Map.EntryMap中內部定義的一個接口,專門用來保存key  value的內容。

4.HashMap類與TreeMap

1HashMap存儲結構使用哈希表,使用「鍵」進行散列存放。因此根據「鍵」去「值」的效率很高

2TreeMap中的「key-value」對的「key」必須是「排序」的。

5.HashTable

1)舊版的Hashtable,操做大多跟HashMap相同,只是它保證線程的同步。

2)它有一個子類Properties(屬性集)比較經常使用:

*Properties 類表示了一個持久的屬性集。Properties 可保存在流中或從流中加載。屬性集中每一個鍵及其對應值都是一個字符串

*不建議使用 put putAll 這類存放元素方法,應該使用 setProperty(String key, String value)方法,由於存放的「鍵-值」對都是字符串。相似取值也應該使用getProperty(String key)

例(以Properties類舉例):

package mapdemo;

 

import java.util.Properties;

 

public class PropertiesDemo {

 

    public static void main(String[] args) {

        Properties pro=new Properties();

        pro.setProperty("張三丰","149歲");

        pro.setProperty("奧運會","08中國");

        pro.setProperty("游泳冠軍","孫楊");

        pro.setProperty("六脈神劍","段譽");

        pro.setProperty("降龍十八掌","郭靖");

        System.out.println("根據鍵找到對應的值:"+pro.getProperty("奧運會"));

        System.out.println(pro.getProperty("游泳冠軍","  "));

        System.out.println(pro.getProperty("iguihejg","沒有 找到對應的值,這是默認值~~~ "));

    }

 

}

運行結果爲:

根據鍵找到對應的值:08中國

孫楊

沒有 找到對應的值,這是默認值~~~

  1. HashMapHashtable區別:

    (1) HashMap不一樣步,Hashtable同步

    (2) HashMap能夠存儲nullnull值,Hashtable不能夠

    (3) HashMap多線程操做環境下效率高,Hashtable多線程操做環境下效率低

    例(以Map集合及其經常使用方法爲例):

    package mapdemo;

     

    import java.util.Collection;

    import java.util.HashMap;

    import java.util.Map;

    import java.util.Set;

     

    public class HashMapDemo {

     

    public static void main(String[] args) {

    HashMap<String, String> map=new HashMap<>();

    map.put("country", "中國");

    map.put("name", "令狐沖");

    map.put("apple", "蘋果");

    map.put("banana", "香蕉");

    map.put("sing", "唱歌");

    map.put("map", "集合");

    System.out.println("原始集合鍵值對數:"+map.size());

    System.out.println("集合中以country爲Key的鍵值是:"+map.get("country"));

    map.remove("name");//移除name鍵值對

    System.out.println("移除name集合中以name爲Key的鍵值是:"+map.get("name"));

    System.out.println("如今集合鍵值對數:"+map.size());

    System.out.println("集合中包括key是banana的鍵值對嗎? "+map.containsKey("banana"));

    System.out.println("集合中包括value是蘋果的鍵值對嗎? "+map.containsValue("蘋果"));

    Set<String>set=map.keySet();

    System.out.println("獲取集合中全部的key,遍厲得:");

    for(String str:set){

    System.out.print(str+"   ");

    }

    System.out.println();

    System.out.println("獲取集合中全部的value值,並遍厲得:");

    Collection<String> set1=map.values();

    for(String  str:set1){

    System.out.print(str+"\t");

    }

    System.out.println();

    System.out.println("**********遍厲集合中的全部鍵值對*********");

    Set<Map.Entry<String, String>> setEntry=map.entrySet();

    for(Map.Entry<String, String> ma:setEntry){

    System.out.println(ma.getKey()+"========>"+ma.getValue());

    }

    }

     

    }

    運行結果爲:

    原始集合鍵值對數:6

    集合中以country爲Key的鍵值是:中國

    移除name集合中以name爲Key的鍵值是:null

    如今集合鍵值對數:5

    集合中包括key是banana的鍵值對嗎? true

    集合中包括value是蘋果的鍵值對嗎? true

    獲取集合中全部的key,遍厲得:

    banana   country   apple   sing   map   

    獲取集合中全部的value值,並遍厲得:

    香蕉 中國 蘋果 唱歌 集合

    **********遍厲集合中的全部鍵值對*********

    banana========>香蕉

    country========>中國

    apple========>蘋果

    sing========>唱歌

    map========>集合

三.異常機制

  1. 異常的概念:異常是指在程序的運行過程當中所發生的不正常的事件,它會中斷正在運行的程序

  2. Java中如何進行異常處理:Java的異常處理是經過5個關鍵字來實現的:

    (1)try執行可能產生異常的代碼

    (2)Catch捕獲異常

    (3)Finally不管是否產生異常總能執行的代碼

    *其上三個 關鍵字 都屬於捕獲異常的範疇

    (4)throws聲明方法可能要拋出的各類異常

    *throws屬於聲明異常

    (5)Throw手動跑出異常對象

    *throw屬於拋出異常

3.Java程序編譯和運行時所發生的問題有兩大類:

 (1)錯誤(Error):JVM系統內部錯誤或資源耗盡等嚴重狀況-屬於JVM須要負擔的責任

 (2)異常(Exception):其它因編程錯誤或偶然的外在因素致使的通常性問題。

 *程序員只能處理異常而對錯誤無能爲力

4.異常處理機制的原理:Java程序在執行過程當中若是出現異常,會自動生成一個異常類對象,該異常類對象將被自動提交給JVM(在程序沒有顯式處理異常的情下),這個過程稱爲拋出異常(throw

5.異常的分類:

1)檢查時異常(E xception)SQLException,

IOException,

ClassNotFoundException,

......

例(檢查時異常):

package exceptiondemo;

 

import java.io.IOException;

 

public class CheckExceptionDemo {

 

    public static void main(String[] args) {

        Runtime run=Runtime.getRuntime();

        try {

            run.exec("clac");

        } catch (IOException e) {

            System.out.println(e.getMessage());

        }

    }

 

}

運行結果爲:

Cannot run program "clac": CreateProcess error=2, 系統找不到指定的文件。

(2)運行時異常(RunTimeException):NullPointerException,

                                ArithmeticExcepttion,

                                ClassCastExceptioion,

                               ArrayIndexOutOfBundsException,

                               .......

 

3)常見異常:(RunTimeException

    ArithmeticException:數學計算異常

    NullPointerException:空指針異常

    ArrayOutOfBoundsException:數組索引越界異常

    ClassCastException:類型轉換異常

6.ExceptionRuntimeException

1Exception在程序中是必須進行處理

2RuntimeException能夠不使用trycatch進行處理,可是若是有異常產生,則異常將由JVM進行處理。

7.處理異常的方法:

*使用try-catch塊捕獲異常,catch塊能夠有多個

格式以下:

public void method(){

    try {

           // 代碼段(此處可能產生異常)

    } catch (異常類型 ex) {

           // 對異常進行處理的代碼段

    }

        // 代碼段

}

例(以0做爲除數爲例):

package exceptiondemo;

 

public class TryCatchDemo {

 

    public static void main(String[] args) {

        try {

            int a=99;

            int b=0;

            int temp=a/b;

        } catch (Exception e) {

            System.out.println("產生異常了~~~");

            System.out.println("輸出捕獲道德異常"+e.getMessage());

        }

        System.out.println("程序繼續向下運行!!。。。。");

        }

 

    }

運行結果爲:

產生異常了~~~

輸出捕獲道德異常/ by zero

程序繼續向下運行!!。。。。

 

 

 

 

8.常見的異常類型:

異常類型

說明

Exception

異常層次結構的父類

ArithmeticException

算數錯誤情形,如以0做除數

ArrayIndexOutOfBoundsException

數組下標越界

NullPointerException

嘗試訪問null對象成員

ClassNotFoundException

不能加載所需的類

IllegalArgumentException

方法接收到非法參數

ClassCastException

對象強制類型轉換出錯

NumberFormatException

數字格式轉換異常,例「abc」轉換成數字

9.try--catch--finally

(1)在try--catch模塊後加上finally代碼塊,不管是否發生異常,finally中的代碼都會執行

(2)有一種狀況例外:在try--cathch塊後加了System.exit(0),會直接關閉JVM

例(仍是以0做除數爲例):

package exceptiondemo;

 

public class FinallyDemo {

 

public static void main(String[] args) {

try {

int result=divide(99,0);

System.out.println("計算結果爲:"+result);

} catch (Exception e) {

System.out.println("出現異常了~~~~");

System.out.println("輸出異常信息:"+e.getMessage());

}finally{

System.out.println("進入finally塊程序繼續運行:");

int x=1;

int y=1;

int temp=x+y;

System.out.println("計算結果爲:"+temp);

}

System.out.println("進入主方法程序繼續向下運行!!!!!!");

}

public static int divide(int x,int y){

int result=x/y;

return result;

}

 

}

運行結果爲:

出現異常了~~~~

輸出異常信息:/ by zero

進入finally塊程序繼續運行:

計算結果爲:2

進入主方法程序繼續向下運行!!!!!!

 

10.多重catch塊(引起多種類型的異常):

1)排列catch塊語句順序:先子類後父類

2)發生異常時按順序逐個匹配

3)只執行第一個與異常類型匹配的catch語句

格式:

public void method(){

try {

      // 代碼段

      // 產生異常(異常類型2)

} catch (異常類型1 ex) {

       // 對異常進行處理的代碼段

} catch (異常類型2 ex) {

      // 對異常進行處理的代碼段

} catch (異常類型3 ex) {

      // 對異常進行處理的代碼段

}

// 代碼段

}

例(挨個捕捉異常):

package exception;

 

public class RuntimeExceptionDemo {

 

public static void main(String[] args) {

int a=100;

int b=0;

String str=null;

int[] array=new int[5];

try{

array[5]=100;

str.equals("abc");

int c=a/b;

}catch(NullPointerException e){

System.out.println("空指針異常~~~");

}catch(ArithmeticException e){

System.out.println("算數異常~~~");

}catch(Exception e){

System.out.println("以上catch都沒有捕獲到異常,由最大父類Exception處理異常");

}finally{

System.out.println("進入finally不管異常是否發生,都會執行");

}

 

System.out.println("main()方法執行完畢!");

 

}

 

}

運行結果爲:

以上catch都沒有捕獲到異常,由最大父類Exception處理異常

進入finally不管異常是否發生,都會執行

main()方法執行完畢!

 

11.try---finallytryfinally 不能捕獲異常 ,僅僅用來當發生異常時,用來釋放資源

格式:

public void method(){

try {

      // 代碼段 1

      // 產生異常的代碼段 2

}finally{

       // 代碼段 3

}

}

例(以0做除數爲例):

package exceptiondemo;

 

public class TryFinallyDemo {

 

    public static void main(String[] args) {

        try {

        int x=88;

        int y=0;

        int temp=x/y;

        System.out.println("計算結果爲:"+temp);

        } finally {

            System.out.println("用於釋放資源");

    }

 

 

}

 

}

運行結果爲:

用於釋放資源

Exception in thread "main" java.lang.ArithmeticException: / by zero

at exceptiondemo.TryFinallyDemo.main(TryFinallyDemo.java:9)

由結果可知try--finally不會捕獲異常,只用於釋放資源

12.throwthrows的區別:

(1)throw用來手動拋出異常

(2)Throws用於方法聲明處,用於拋出該方法體內部可能發生的異常類型。一旦在方法聲明處經過throws拋出某種類型的異常,則在該方  法體內部就不用處理該類型的異常,交給方法調用到處理該類型的異常。

1(手動拋出異常):

 package throwdemo;

 

public class ThrowDemo {

 

    public static void main(String[] args) {

        try {

        int[] a=new int[3];

        System.out.println(a[4]);

        //throw new  ArrayIndexOutOfBoundsException();

        } catch (Exception e) {

            System.out.println("發生了數組越界異常~~~");

        }

    }

 

}

運行結果爲:

發生了數組越界異常~~~

2throws聲明異常):

package throwsdemo;

 

public class ThrowsDemo {

 

    public static void main(String[] args) {

        try {

        int result=divide(88,2);

        System.out.println("計算結果爲:"+result);

        } catch (Exception e) {

            System.out.println(e.getMessage());

            e.printStackTrace();

        }

 

    }

    public static int divide(int x,int y) throws Exception{

        int result=x/y;

        return result;

    }

}

運行結果爲:

計算結果爲:44

*注意在調用異常聲明方法是,若是不知道如何處理異常,也可以使用throw關鍵字繼續將異常拋出,這樣程序也能夠編譯經過,但程序一旦發生異常,若是程序沒有被處理,程序就會非正常終止

例:

package throwsdemo;

 

public class ThrowsDemo01 {

 

    public static void main(String[] args) throws Exception {

        int result=divide(88,0);

        System.out.println("計算結果爲:"+result);

    }

    public static int divide(int x,int y) throws Exception{

        int result=x/y;

        return result;

    }

}

運行結果爲:

Exception in thread "main" java.lang.ArithmeticException: / by zero

at throwsdemo.ThrowsDemo01.divide(ThrowsDemo01.java:10)

at throwsdemo.ThrowsDemo01.main(ThrowsDemo01.java:6)

13.自定義異常:

1)建立自定義異常:繼承自Exception 。習慣上包裝一下父類的構造方法。

格式:

public class MyException extends Exception {

public MyException() {     

   super();  

  }

    public MyException(String msg) {       

       super(msg);    

    }

}

2)使用自定義異常:

格式:

public String[] createArray(int length) throws MyException {

    if (length < 0) {    

        throw new MyException("數組長度小於0,不合法");

    }

    return new String[length];

}

 

1(以上述自定義異常和使用自定義異常爲例):

自定義異常類(繼承父類Exception):

package throwexception;

 

public class DivideByMinusException extends Exception{

    public DivideByMinusException(){

        super();

    }

    public DivideByMinusException(String message){

        super(message);

    }

}

測試自定義異常類:

package throwexception;

 

public class ThrowExceptionDemo {

 

    public static void main(String[] args) {

        try {

        int  result=divide(55,-5);

        System.out.println("計算結果爲:"+result);

    } catch (DivideByMinusException e) {

        System.out.println(e.getMessage());

    }

 

}

public  static int divide(int x,int y) throws DivideByMinusException{

    if(y<0){

        throw new DivideByMinusException("被除數是負數~~~");

    }

        int result=x/y;

        return result;

    }

}

運行結果爲:

被除數是負數~~~

2(以貨船載貨爲例自定義異常):

自定義LoadException異常:

package boat;

 

public class LoadException  extends Exception{

    public LoadException(){

    super();

    }

    public LoadException(String message){

    super(message);

    }

}

貨船模擬裝貨類:

package boat;

 

public class Boat {

    private static final int MAX_STORE=1000;

    private int currentStore;

 

    public void load(int num) throws LoadException{

        System.out.println("貨船裝貨前當前載貨量:"+currentStore);

        currentStore+=currentStore;//模擬裝貨

        System.out.println("貨船裝貨後的當前載貨量:"+currentStore);

        if(currentStore>MAX_STORE){

            System.out.println("已超載,貨船面臨乘船危險~~");

        }

    }

}

測試貨船裝貨類:

package boat;

 

import java.util.Scanner;

 

public class TestBoat {

 

    public static void main(String[] args) {

        Boat bo=new Boat();

        while(true){

        Scanner scan=new Scanner(System.in);

        System.out.print("請輸入要載入載貨量:");

        int cur=scan.nextInt();

        try {

            bo.load(cur);

        } catch (LoadException e) {

            System.out.println("輸出 捕獲的異常:"+e.getMessage());

            break;

        }

        scan.close();

    }

 

}

 

}

*小結(finally易錯點):

例:

package easyeorror;

 

public class FinallyDemo {

 

    public static void main(String[] args) {

        int result=divide(4,6);

        System.out.println("所返回 的結果是:"+result);

    }

    public static int divide(int x,int y){

        try {

        int temp=x+y;

        return temp;

        } catch (Exception e) {

            System.out.println("發生異常了~~~~~~~");

        }finally{

            int result=x*y;

            return result;

    }

}

 

}

運行結果爲:

所返回 的結果是:24

 

【本次總結完畢】

 

2018.1.12

相關文章
相關標籤/搜索