Java基礎 語法筆記

Hygge-1024發表於2024-03-07

大二學習Java語法時,上課寫的部分筆記,可能並不完整,僅用以作紀念。

陣列、集合、字串(第六課)

目錄
  • 陣列、集合、字串(第六課)
      • 陣列
      • 集合類
        • Collection介面:
        • 泛型:
        • List:
          • ArrayList:
          • LinkedList類
        • Set
          • HashSet類
          • TreeSet類
        • Map
        • Lterator介面
        • Vector類
        • Collections類
      • 查詢、替換操作
      • 複製
    • String
        • toString()
        • String的常用方法(11)
        • 數字轉換為字串
        • 讀取檔案:
        • StringTokenizer類
        • 字串與字元、位元組陣列
        • StringBuffer類
        • StringBuilder類
  • 異常
      • 介紹
      • 討論Exception型別異常:
      • Java中Error和Exception的異常同
    • 異常處理機制:
        • try catch finally執行順序
      • throws 和 throw:宣告和丟擲異常
        • throws宣告異常
        • 方法重寫時宣告丟擲異常的限制
        • throw丟擲異常
        • throw new 語句的執行順序
      • 子類繼承父類異常
  • 輸入輸出流
      • 輸入流
      • 輸出流
        • 檢視系統預設編碼

陣列

陣列:同類資料的定長集合

一維陣列、二維陣列

int list[] = {1,2,3}; int len = list.length

集合類

集合:集合存放物件,非基本型別資料

Collection介面:

介面方法

方法名稱 說明
boolean add(E e) 向集合中新增一個元素,如果集合物件被新增操作改變了,則返回 true。E 是元素的資料型別
boolean addAll(Collection c) 向集合中新增集合 c 中的所有元素,如果集合物件被新增操作改變了,則返回 true。
void clear() 清除集合中的所有元素,將集合長度變為 0。
boolean contains(Object o) 判斷集合中是否存在指定元素
boolean containsAll(Collection c) 判斷集合中是否包含集合 c 中的所有元素
boolean isEmpty() 判斷集合是否為空
Iteratoriterator() 返回一個 Iterator 物件,用於遍歷集合中的元素
boolean remove(Object o) 從集合中刪除一個指定元素,當集合中包含了一個或多個元素 o 時,該方法只刪除第一個符合條件的元素,該方法將返回 true。
boolean removeAll(Collection c) 從集合中刪除所有在集合 c 中出現的元素(相當於把呼叫該方法的集合減去集合 c)。如果該操作改變了呼叫該方法的集合,則該方法返回 true。
boolean retainAll(Collection c) 從集合中刪除集合 c 裡不包含的元素(相當於把呼叫該方法的集合變成該集合和集合 c 的交集),如果該操作改變了呼叫該方法的集合,則該方法返回 true。
int size() 返回集合中元素的個數
Object[] toArray() 把集合轉換為一個陣列,所有的集合元素變成對應的陣列元素。

泛型:

class GenericFoo<T>{

}

List:

List介面: public interface List extends Collection

是Collection介面的子介面,列表,有順序的集合提供的方法:

(部分!!!)E remove (int index):移除列表中指定位置的元素

int [indexOf]:返回列表中首次出現指定元素的索引,如果列表不包含此元素,則返回 -1

Java List集合:ArrayList和LinkedList類的用法及區別 (biancheng.net)

它主要由兩個常用的實現類:ArrayList類和LinkedList類:

ArrayList:

ArrayList 類實現了可變陣列的大小,儲存在內的資料稱為元素。它還提供了快速基於索引訪問元素的方式,對尾部成員的增加和刪除支援較好。缺點:插入與刪除速度相對較慢。

方法名稱 說明
E get(int index) 獲取此集合中指定索引位置的元素,E 為集合中元素的資料型別
int index(Object o) 返回此集合中第一次出現指定元素的索引,如果此集合不包含該元 素,則返回 -1
int lastIndexOf(Object o) 返回此集合中最後一次出現指定元素的索引,如果此集合不包含該 元素,則返回 -1
E set(int index, Eelement) 將此集合中指定索引位置的元素修改為 element 引數指定的物件。 此方法返回此集合中指定索引位置的原元素
List subList(int fromlndex, int tolndex) 返回一個新的集合,新集合中包含 fromlndex 和 tolndex 索引之間 的所有元素。包含 fromlndex 處的元素,不包含 tolndex 索引處的 元素
public static void main(String[] args) {
		List<Integer> list = new ArrayList<Integer>();
			list.add(new Integer(6));
			list.add(new Integer(9));
			list.add(new Integer(3));
			list.add(new Integer(5));
			list.add(new Integer(6));
			Iterator<Integer> it = list.iterator();
			while(it.hasNext()){
				System.out.println(it.next());
			}
		}
//這裡是是建立的Integer類
//使用演示1
class Product {
    // 商品類
    private int id; // 商品編號
    private String name; // 名稱
    private float price; // 價格
    public Product(int id, String name, float price) {
        this.name = name;
        this.id = id;
        this.price = price;
    }
    // 這裡是上面3個屬性的setter/getter方法,這裡省略
    public String toString() {
        return "商品編號:" + id + ",名稱:" + name + ",價格:" + price;
    }
}

public class Test {
    public static void main(String[] args) {
        Product pd1 = new Product(4, "木糖醇", 10);
        Product pd2 = new Product(5, "洗髮水", 12);
        Product pd3 = new Product(3, "熱水壺", 49);
        List list = new ArrayList(); // 建立集合
        //List<Product> list = new ArrayList();一般可能是這樣寫的
        list.add(pd1);
        list.add(pd2);
        list.add(pd3);
        System.out.println("*************** 商品資訊 ***************");
        for (int i = 0; i < list.size(); i++) {
            // 迴圈遍歷集合,輸出集合元素
            Product product = (Product) list.get(i);//與 Set 不同的是,List 集合中存在 get() 方法,該方法可以透過索引來獲取所對應的值,獲取的值為 Object 類,因此需要將該值轉換為 Product 類
            System.out.println(product);//因為上面重寫了toStirng()
        }
    }
}
//使用演示2 indexOf() lastIndexOf()
public static void main(String[] args) {
    List list = new ArrayList();
    list.add("One");
    list.add("|");
    list.add("Two");
    list.add("|");
    list.add("Three");
    list.add("|");
    list.add("Four");
    System.out.println("list 集合中的元素數量:" + list.size());
    System.out.println("list 集合中的元素如下:");
    Iterator it = list.iterator();//轉換成Iterator方便遍歷
    while (it.hasNext()) {
        System.out.print(it.next() + "、");
    }
    System.out.println("\n在 list 集合中'丨'第一次出現的位置是:" + list.indexOf("|"));
    System.out.println("在 list 集合中'丨'最後一次出現的位置是:" + list.lastIndexOf("|"));
}
/*
list 集合中的元素數量:7
list 集合中的元素如下:
One、|、Two、|、Three、|、Four、
在 list 集合中'|'第一次出現的位置是:1
在 list 集合中'|'最後一次出現的位置是:5
*/
//subList() 的用法  
List sublist = new ArrayList();
    sublist = list.subList(2, 5); // 從list集合中擷取索引2~5的元素,儲存到sublist集合中
LinkedList類

LinkedList 類採用連結串列結構儲存物件,這種結構的優點是便於向集合中插入或者刪除元素。

需要頻繁向集合中插入和刪除元素時,使用 LinkedList 類比 ArrayList 類效果高,但是 LinkedList 類隨機訪問元素的速度則相對較慢。這裡的隨機訪問是指檢索集合中特定索引位置的元素。

除Collection介面和List介面的所有方法外,還有的介面

方法名稱 說明
void addFirst(E e) 將指定元素新增到此集合的開頭
void addLast(E e) 將指定元素新增到此集合的末尾
E getFirst() 返回此集合的第一個元素
E getLast() 返回此集合的最後一個元素
E removeFirst() 刪除此集合中的第一個元素
E removeLast() 刪除此集合中的最後一個元素
public class Test {
    public static void main(String[] args) {
        LinkedList<String> products = new LinkedList<String>(); // 建立集合物件
        String p1 = new String("六角螺母");
        String p2 = new String("10A 電纜線");
        String p3 = new String("5M 捲尺");
        String p4 = new String("4CM 原木方板");
        products.add(p1); // 將 p1 物件新增到 LinkedList 集合中
        products.add(p2); // 將 p2 物件新增到 LinkedList 集合中
        products.add(p3); // 將 p3 物件新增到 LinkedList 集合中
        products.add(p4); // 將 p4 物件新增到 LinkedList 集合中
        String p5 = new String("標準資料夾小櫃");
        products.addLast(p5); // 向集合的末尾新增p5物件
        System.out.print("*************** 商品資訊 ***************");
        System.out.println("\n目前商品有:");
        for (int i = 0; i < products.size(); i++) {
            System.out.print(products.get(i) + "\t");
        }
        System.out.println("\n第一個商品的名稱為:" + products.getFirst());
        System.out.println("最後一個商品的名稱為:" + products.getLast());
        products.removeLast(); // 刪除最後一個元素
        System.out.println("刪除最後的元素,目前商品有:");
        for (int i = 0; i < products.size(); i++) {
            System.out.print(products.get(i) + "\t");
        }
    }
}
/*
*************** 商品資訊 ***************
目前商品有:
六角螺母    10A 電纜線    5M 捲尺    4CM 原木方板    標準資料夾小櫃   
第一個商品的名稱為:六角螺母
最後一個商品的名稱為:標準資料夾小櫃
刪除最後的元素,目前商品有:
六角螺母    10A 電纜線    5M 捲尺    4CM 原木方板
*/

LinkedList 中的 Java 中的泛型,用於指定集合中元素的資料型別,例如這裡指定元素型別為 String,則該集合中不能新增非 String 型別的元素。

ArrayList 類和 LinkedList 類的區別

ArrayList 與 LinkedList 都是 List 介面的實現類,因此都實現了 List 的所有未實現的方法,只是實現的方式有所不同。

ArrayList 是基於動態陣列資料結構的實現,訪問元素速度優於 LinkedList。LinkedList 是基於連結串列資料結構的實現,佔用的記憶體空間比較大,但在批次插入或刪除資料時優於 ArrayList。

對於快速訪問物件的需求,使用 ArrayList 實現執行效率上會比較好。需要頻繁向集合中插入和刪除元素時,使用 LinkedList 類比 ArrayList 類效果高。

不同的結構對應於不同的演算法,有的考慮節省佔用空間,有的考慮提高執行效率,對於程式設計師而言,它們就像是“熊掌”和“魚肉”,不可兼得。高執行速度往往是以犧牲空間為代價的,而節省佔用空間往往是以犧牲執行速度為代價的。

Set

不包含重複元素的集合,並且最多只允許包含一個 null 元素,模擬數學上的 “集合”,未引入新的方法,與List的區別是,List元素有位置概念,Set集合只有元。

Set 是Collection介面的子介面,它主要有兩個常用的實現類:HashSet 類和 TreeSet類。

HashSet類

HashSet 是 Set 介面的典型實現,大多數時候使用 Set 集合時就是使用這個實現類。HashSet 是按照 Hash 演算法來儲存集合中的元素。因此具有很好的存取和查詢效能。

HashSet 具有以下特點:

  • 不能保證元素的排列順序,順序可能與新增順序不同,順序也有可能發生變化。
  • HashSet 不是同步的,如果多個執行緒同時訪問或修改一個 HashSet,則必須透過程式碼來保證其同步。
  • 集合元素值可以是 null。

當向 HashSet 集合中存入一個元素時,HashSet 會呼叫該物件的 hashCode() 方法來得到該物件的 hashCode 值,然後根據該 hashCode 值決定該物件在 HashSet 中的儲存位置。如果有兩個元素透過 equals() 方法比較返回的結果為 true,但它們的 hashCode 不相等,HashSet 將會把它們儲存在不同的位置,依然可以新增成功。也就是說,兩個物件的 hashCode 值相等且透過 equals() 方法比較返回結果為 true,則 HashSet 集合認為兩個元素相等。

下面的程式碼演示了建立兩種不同形式的 HashSet 物件。

HashSet hs = new HashSet();    // 呼叫無參的建構函式建立HashSet物件
HashSet<String> hss = new HashSet<String>();    // 建立泛型的 HashSet 集合物件

例子1、編寫一個 Java 程式,使用 HashSet 建立一個 Set 集合,並向該集合中1新增 4 套教程。具體實現程式碼如下:

public static void main(String[] args) {
    HashSet<String> courseSet = new HashSet<String>(); // 建立一個空的 Set 集合
    String course1 = new String("Java入門教程");
    String course2 = new String("Python基礎教程");
    String course3 = new String("C語言學習教程");
    String course4 = new String("Golang入門教程");
    courseSet.add(course1); // 將 course1 儲存到 Set 集合中
    courseSet.add(course2); // 將 course2 儲存到 Set 集合中
    courseSet.add(course3); // 將 course3 儲存到 Set 集合中
    courseSet.add(course4); // 將 course4 儲存到 Set 集合中
    System.out.println("C語言中文網教程有:");
    
    Iterator<String> it = courseSet.iterator();
    
    while (it.hasNext()) {
        System.out.println("《" + (String) it.next() + "》"); // 輸出 Set 集合中的元素
    }
    System.out.println("有" + courseSet.size() + "套精彩教程!");
}
/*
C語言中文網教程有:
《Java入門教程》
《C語言學習教程》
《Python基礎教程》
《Golang入門教程》
有4套精彩教程!
*/
TreeSet類

TreeSet 類同時實現了 Set 介面和 SortedSet 介面。SortedSet 介面是 Set 介面的子介面,可以實現對集合進行自然排序,因此使用 TreeSet 類實現的 Set 介面預設情況下是自然排序的,這裡的自然排序指的是升序排序

注意:在使用自然排序時只能向 TreeSet 集合中新增相同資料型別的物件,否則會丟擲 ClassCastException 異常。

TreeSet 只能對實現了 Comparable 介面的類物件進行排序,因為 Comparable 介面中有一個 compareTo(Object o) 方法用於比較兩個物件的大小。例如 a.compareTo(b),如果 a 和 b 相等,則該方法返回 0;如果 a 大於 b,則該方法返回大於 0 的值;如果 a 小於 b,則該方法返回小於 0 的值。

實現Comparable介面類物件的比較方法:

比較方式
包裝類(BigDecimal、Biglnteger、 Byte、Double、 Float、Integer、Long 及 Short) 按數字大小比較
Character 按字元的 Unicode 值的數字大小比較
String 按字串中字元的 Unicode 值的數字大小比較

TreeSet類的常用方法

方法名稱 說明
E first() 返回此集合中的第一個元素。其中,E 表示集合中元素的資料型別
E last() 返回此集合中的最後一個元素
E poolFirst() 獲取並移除此集合中的第一個元素
E poolLast() 獲取並移除此集合中的最後一個元素
SortedSet subSet(E fromElement,E toElement) 返回一個新的集合,新集合包含原集合中 fromElement 物件與 toElement 物件之間的所有物件。包含 fromElement 物件,不包含 toElement 物件
SortedSet headSet<E toElement〉 返回一個新的集合,新集合包含原集合中 toElement 物件之前的所有物件。 不包含 toElement 物件
SortedSet tailSet(E fromElement) 返回一個新的集合,新集合包含原集合中 fromElement 物件之後的所有對 象。包含 fromElement 物件
public class Test08{
    public static void main(String[] args){
        TreeSet<Double> scores = new TreeSet<Double>();//建立 TreeSet集合
        Scanner input = new Scanner(System.in);
        System.out.println("------------學生成績管理系統-------------");
        for(int i = 0; i < 5; i++){
             System.out.println("第" + (i + 1) + "個學生成績:");
            double score = input.nextDouble();
             // 將學生成績轉換為Double型別,新增到TreeSet集合中	
            scores.add(Double.valueOf(score));
        }
        Iterator<Double> it = scores.iterator();//建立Iterator物件
         System.out.println("學生成績從低到高的排序為:");
        while(it.hasNext()){
            System.out.print(it.next() + '\t');
        }
         System.out.println("\n請輸入要查詢的成績:");
        double searchScore = input.nextDouble();
        if(scores.contains(searchScore)){//contains()函式是Set類中的
              System.out.println("成績為: " + 	searchScore + " 的學生存在!");
        } else {
            System.out.println("成績為: " + searchScore + " 的學生不存在!");
        }
         // 查詢不及格的學生成績
        SortedSet<Double> score1 = scores.headSet(60.0);
        for(int i = 0; i < score1.toArray().length; i++){//toArray()將集合 轉換成字串陣列。
           System.out.print(score1.toArray()[i] + "\t"); 
        }
        // 查詢90分以上的學生成績
        SortedSet<Double> score2 = scores.tailSet(90.0);
        System.out.println("\n90 分以上的成績有:");
        for (int i = 0; i < score2.toArray().length; i++) {
            System.out.print(score2.toArray()[i] + "\t");
        }
    }
}

Map

是一組成對的<鍵-值>物件,Map 集合中的每一個元素都包含一個鍵(key)物件和一個值(value)物件。用於儲存具有對映關係的資料。

Map 的 key 不允許重複,value 可以重複,即同一個 Map 物件的任何兩個 key 透過 equals 方法比較總是返回 false。

包含HashMap、TreeMap、LinkedHashMap、Hashtable……

注意:TreeMap 類的使用方法與 HashMap 類相同,唯一不同的是 TreeMap 類可以對鍵物件進行排序

方法名稱 說明
void clear() 刪除該 Map 物件中的所有 key-value 對。
boolean containsKey(Object key) 查詢 Map 中是否包含指定的 key,如果包含則返回 true。
boolean containsValue(Object value) 查詢 Map 中是否包含一個或多個 value,如果包含則返回 true。
V get(Object key) 返回 Map 集合中指定鍵物件所對應的值。V 表示值的資料型別
V put(K key, V value) 向 Map 集合中新增鍵-值對,如果當前 Map 中已有一個與該 key 相等的 key-value 對,則新的 key-value 對會覆蓋原來的 key-value 對。
void putAll(Map m) 將指定 Map 中的 key-value 對複製到本 Map 中。
V remove(Object key) 從 Map 集合中刪除 key 對應的鍵-值對,返回 key 對應的 value,如果該 key 不存在,則返回 null
boolean remove(Object key, Object value) 這是 Java 8 新增的方法,刪除指定 key、value 所對應的 key-value 對。如果從該 Map 中成功地刪除該 key-value 對,該方法返回 true,否則返回 false。
Set entrySet() 返回 Map 集合中所有鍵-值對的 Set 集合,此 Set 集合中元素的資料型別為 Map.Entry
Set keySet() 返回 Map 集合中所有鍵物件的 Set 集合
boolean isEmpty() 查詢該 Map 是否為空(即不包含任何 key-value 對),如果為空則返回 true。
int size() 返回該 Map 裡 key-value 對的個數
Collection values() 返回該 Map 裡所有 value 組成的 Collection
 public static void main(String[] args) {
        HashMap users = new HashMap();
        users.put("11", "張浩太"); // 將學生資訊鍵值對儲存到Map中
        users.put("22", "劉思誠");
        users.put("33", "王強文");
        users.put("44", "李國量");
        users.put("55", "王路路");
        System.out.println("******** 學生列表 ********");
        Iterator it = users.keySet().iterator();//將users 裡的key值提取出來存入 it中
        while (it.hasNext()) {
            // 遍歷 Map
            Object key = it.next();
            Object val = users.get(key);
            System.out.println("學號:" + key + ",姓名:" + val);
        }
        Scanner input = new Scanner(System.in);
        System.out.println("請輸入要刪除的學號:");
        int num = input.nextInt();
        if (users.containsKey(String.valueOf(num))) { // 判斷是否包含指定鍵
            users.remove(String.valueOf(num)); // 如果包含就刪除
        } else {
            System.out.println("該學生不存在!");
        }
        System.out.println("******** 學生列表 ********");
        it = users.keySet().iterator();
        while (it.hasNext()) {
            Object key = it.next();
            Object val = users.get(key);
            System.out.println("學號:" + key + ",姓名:" + val);
        }
    }

1.在 for 迴圈中使用 entries 實現 Map 的遍歷(最常見和最常用的)。

public static void main(String[] args) {
	Map<String,String> map = new HashMap<String,String>();
    map.put("Java入門教程", "http://c.biancheng.net/java/");
    map.put("C語言入門教程", "http://c.biancheng.net/c/");
    for(Map.Entry<String,String> entry : map.entrySet()){
        String mapKey = entry.getKey();
        String mapValue = entry.getValue();
        System.out.println(mapKey +":" + mapValue);
    }
    
}

2.使用 for-each 迴圈遍歷 key 或者 values,一般適用於只需要 Map 中的 key 或者 value 時使用。效能上比 entrySet 較好。

Map<String,String> map = new HashMap<String,String>();
map.put("Java入門教程", "http://c.biancheng.net/java/");
map.put("C語言入門教程", "http://c.biancheng.net/c/");
//列印鍵集合
for(String key:map.keySet()){
    System.out.println(key);
}
//列印值集合
for(String value:map.values()){
    System.out.println(val);
}

3.使用迭代器(Iterator)遍歷

Map<String,String>map = new HashMap<String,String>();
map.put("Java入門教程", "http://c.biancheng.net/java/");
map.put("C語言入門教程", "http://c.biancheng.net/c/");
Iterator<Entry<String,String>> entries = map.entrySet().iterator();//將鍵值對 轉化為Iterator
while(entires.hasNext()){
    Entry<String,String> entry = entries.next();
    String key = entry.getKey();
    String value = entry.getValue();
    System.out.println(key + ":" + value);
}

4.透過鍵找值遍歷,這種方式的效率比較低,因為本身從鍵取值是耗時的操作。

for(String key : map.ketSet()){
    String value = map.get(key);
    System.out.println(key + ":" + value);
}

主要的方法有:

V put(K key, V value);

V get(Object key);取(以key 取值value))

Lterator介面

迭代器:Iterator 主要用於迭代訪問(即遍歷) collection 中的元 素

列:List<Integer> list = new ArrayList<Integer>();

Iterator<Integer> it = list.iterator();

在Map中使用

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

 Iterator<String> it =keys.iterator();

Vector類

:變長的物件陣列

public class Vector<E>extends AbstractList<E>implements [List]<E>

可以根據下標來引用元素,可以追加物件元素數量,可以修改、刪除其中的物件。

Vector 的大小可以根據需要增大或縮小,以適應建立 Vector 後進行新增或移除項的操作。

建立Vector:不必須指明序列中元素的型別,可在使用時確定。——Vector myVector = new Vector(100,50);//自動增加量

注:使用Vector時一定要先建立後使用,否則會出現堆疊溢位或使用null指標等異常——Vdctor a; ——a.add("abc");

addElement(Object obj):將新元素新增在向量序列的尾部

insertElement(Object obj,int index):將新元素插入在序列的指定位置處

修改與刪除

void setElementAt(Object obj,int dex):將index位置處的物件設定成obj

Boolean removeElement(Object obj):刪除向量中第一個與指定的obj物件相同的元素,同時將後面元素前補上空位

void removeElementAt(int index):刪除index指定位置處的元素,同時將後面的元素向前提

void removeAllElements():清除向量中的所有元素

查詢

Object elementAt(int index):返回指定位置index處的元素:
需要強制型別轉換:
D200_Card myCar = (D200_Card) myVector.elementAt(0);

boolean contains(Object obj) : 檢查向量中是否包含物件元素obj

int indexOf(Object obj,int start_index):從start_index位置開始向後搜尋,返回第一個與物件obj相同的元素的位置。若不存在,則返回-1

int lastIndexOf(Object obj,int start_index):從start_index位置開始向前搜尋,返回第一個與物件obj相同的元素的位置。若不存在,則返回-1。

Collections類

Collections 類是 Java 提供的一個操作 Set、List 和 Map 等集合的工具類。Collections 類提供了許多操作集合的靜態方法,藉助這些靜態方法可以實現集合元素的排序、查詢替換和複製等操作。

Collections 提供瞭如下方法用於對 List 集合元素進行排序。

  • void reverse(List list):對指定 List 集合元素進行逆向排序。
  • void shuffle(List list):對 List 集合元素進行隨機排序(shuffle 方法模擬了“洗牌”動作)。
  • void sort(List list):根據元素的自然順序對指定 List 集合的元素按升序進行排序。
  • void sort(List list, Comparator c):根據指定 Comparator 產生的順序對 List 集合元素進行排序。
  • void swap(List list, int i, int j):將指定 List 集合中的 i 處元素和 j 處元素進行交換。Collections.swap(vector, 0, 4);
  • void rotate(List list, int distance):當 distance 為正數時,將 list 集合的後 distance 個元素“整體”移到前面;當 distance 為負數時,將 list 集合的前 distance 個元素“整體”移到後面。該方法不會改變集合的長度。
 ArrayList<Student> list02 = new ArrayList<>();
       list02.add(new Student("a迪麗熱巴",19));
       list02.add(new Student("古力娜扎",20));
       list02.add(new Student("楊冪",18));
       list02.add(new Student("b楊冪",19));
        System.out.println(list02);

      /*此方法簡便!!! 
      Collections.sort(list02, new Comparator<Student>() {
           @Override
           public int compare(Student o1, Student o2) {
               return o1.getAge()-o2.getAge();
           }
       });*/

        //擴充套件:瞭解
        Collections.sort(list02, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //按照年齡排序
                int result = o1.getAge()-o2.getAge();
                //如果兩個人年齡相同,使用姓名的第一個字母比較

                if (result==0){
                  result =  o1.getName().charAt(0)-o2.getName().charAt(0);
                }
                return result;
            }
        });
        System.out.println(list02);
/********************************/
//建立的Student類

public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

查詢、替換操作

Collections 還提供瞭如下常用的用於查詢、替換集合元素的方法。

  • int binarySearch(List list, Object key):使用二分搜尋法搜尋指定的 List 集合,以獲得指定物件在 List 集合中的索引。如果要使該方法可以正常工作,則必須保證 List 中的元素已經處於有序狀態。
  • Object max(Collection coll):根據元素的自然順序,返回給定集合中的最大元素。
  • Object max(Collection coll, Comparator comp):根據 Comparator 指定的順序,返回給定集合中的最大元素。
  • Object min(Collection coll):根據元素的自然順序,返回給定集合中的最小元素。
  • Object min(Collection coll, Comparator comp):根據 Comparator 指定的順序,返回給定集合中的最小元素。
  • void fill(List list, Object obj):使用指定元素 obj 替換指定 List 集合中的所有元素。
  • int frequency(Collection c, Object o):返回指定集合中指定元素的出現次數。
  • int indexOfSubList(List source, List target):返回子 List 物件在父 List 物件中第一次出現的位置索引;如果父 List 中沒有出現這樣的子 List,則返回 -1。
  • int lastIndexOfSubList(List source, List target):返回子 List 物件在父 List 物件中最後一次出現的位置索引;如果父 List 中沒有岀現這樣的子 List,則返回 -1。
  • boolean replaceAll(List list, Object oldVal, Object newVal):使用一個新值 newVal 替換 List 物件的所有舊值 oldVal。

複製

Collections 類的 copy() 靜態方法用於將指定集合中的所有元素複製到另一個集合中。執行 copy() 方法後,目標集合中每個已複製元素的索引將等同於源集合中該元素的索引。

copy() 方法的語法格式如下:

void copy(List <? super T> dest,List<? extends T> src)

其中,dest 表示目標集合物件,src 表示源集合物件。

Collections.copy(destList, srcList);

String

toString()

Java裡面所有的類都有一個共同的父類Object,不管你願不願意都得繼承他(預設繼承,不用加extends),當重寫這個toString類後需要把該類轉換成String類型的時候就會呼叫這個方法。用例toString

String的常用方法(11)

計算字串長度 : int len = String.length();

判斷字串文字是否相等,a.equals(b);->true相等 false不等

public boolean startsWith(String s)

public boolean endsWith(String s)

public boolean regionMatches(int firstStart,String other,int otherStart,int length)比較兩個字串子串是否相同

//例子: 判斷一個字串中共出現幾個en
{   public static void main(String args[])
    {  int number=0; 
       String s="student;entropy;engage,english,client";
       for(int k=0;k<s.length();k++)
        {  
           if(s.regionMatches(k,"en",0, 2))
             { System.out.printf("k=%d\n",k);
               number++;
             }
         } //從k的位置開始取長度為2的字串,從“en”的0開始取長度為2的字串
       System.out.println("number="+number);
    }
}
/*輸出:
    k=4
	k=8
	k=16
	k=23
	k=34
	number=5
*/

public int compareTo(String s)

字串物件可以使用String類中的compareTo(String s)方法,按字典序與引數s指定的字串比較大小。

如果當前字串與s相同,該方法返回值0;如果當前字串物件大於s,該方法返回正值;如果小於s,該方法返回負值。

public int indexOf(String s)

字串呼叫方法indexOf (String s)從當前字串的頭開始檢索字串s,並返回首次出現s的位置。如果沒有檢索到字串s,該方法返回的值是-1。

字串呼叫indexOf(String s ,int startpoint)方法從當前字串的startpoint位置處開始檢索字串s,並返回首次出現s的位置。如果沒有檢索到字串s,該方法返回的值是-1。

字串呼叫lastIndexOf (String s)方法從當前字串的頭開始檢索字串s,並返回最後出現s的位置。如果沒有檢索到字串s,該方法返回的值是-1。

 String tom="I am a good cat";
 System.out.println(tom.indexOf("I"));
 System.out.println(tom.indexOf("a"));
 System.out.println(tom.indexOf("a",7));
 System.out.println(tom.indexOf("good"));
 System.out.println(tom.indexOf("w",2));

public String substring()

字串物件呼叫substring(int startpoint) 方法獲得一個當前字串的子串,該子串是從當前字串的startpoint處擷取到字串的末尾所得到的字串。

字串物件呼叫substring(int start ,int end)方法獲得一個當前字串的子串,該子串是從當前字串的start處擷取到end處所得到的字串,但不包括end處所對應的字元。

String tom="I love them";
String s1=tom.substring(2);
String s2=tom.substring(2,5);
System.out.println(s1);
System.out.println(s2);

public String replaceAll(String oldString,String newString)

字串物件s呼叫該方法,可以透過用引數newString指定的字串替換s中由oldString指定的所有字串而得到的字串;

public String replaceFirst(String oldString,String newString)

換第一個oldString

public String trim()

一個字串s透過呼叫方法trim()得到一個字串物件,該字串物件是s去掉前後空格後的字串

數字轉換為字串

String str=String.valueOf(123.56)

int a = int.parseInt(String a)

物件的字串表示:

  1. Object類有一個public 方法toString(),一個物件透過呼叫該方法可以獲得該物件的字串表示

  2. Object類的toString的實現為預設物件的地址值

  3. 重寫toString方法可以定製化物件字串表示

import java.util.Date;
import java.awt.*;
public class Test6
{  public static void main(String args[])
   {  Date date=new Date();
      Button button=new Button("確定");
      System.out.println(date.toString());
      System.out.println(button.toString());  
   }
}

讀取檔案:

public class Demo4 {
	public static void main(String[] args) {
		String fileone = "C:\\Users\\劉\\Desktop\\實驗七 資料\\top10input.txt";
		File file = new File(fileone);
		ArrayList<Student> student = new ArrayList<>();//建立一個Student的集合
		try {
			Scanner scanner = new Scanner(file);//讀取檔案
			scanner.nextLine();//將檔案首行“學號	     語文	數學 英語”除去
			while(scanner.hasNext()) {
				ArrayList<String> list = new ArrayList<>();//用於儲存讀取的每一行,每次讀取都是新建(比較特殊,while每次都是新的一行)
				for(String x : scanner.nextLine().split("\\s+")) {
					list.add(x);//list 中儲存一行的資訊,例如“23470253144,68,79,60”
					String[] strings = new String[list.size() - 1];
					strings = list.get(0).split(",");
					Student a1 = new Student(strings[0],strings[1],strings[2],strings[3]);
					a1.sum();
					student.add(a1);
//					System.out.println(a1.number+" "+a1.a1+" "+a1.a2+" "+a1.a3+" "+a1.sum);
				}//接下來的操作便是 提取他們將其存入student 集合中!!!
//				System.out.println(list.size());
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		//開始依據sum排序,並輸出前10位。
		
	}

}

ArrayList自定義排序

class Student implements Comparable{
	public String number,a1,a2,a3;
	public int sum;
	int math ;
	Student(String number,String a1,String a2,String a3){
		this.number = number;
		this.a1 = a1;
		this.a2 = a2;
		this.a3 = a3;
	}

	void sum() {
		sum = Integer.parseInt(a1) + Integer.parseInt(a2) + Integer.parseInt(a3);
	}
	@Override
	public int compareTo(Object o) {
		// TODO Auto-generated method stub
		Student s = (Student) o;
		this.math = Integer.parseInt(a2);//將其轉為數字型
		s.math = Integer.parseInt(a2);//將其轉為數字型
		if(this.sum > s.sum) {
			return -1;
		} 
		else if(this.sum < s.sum) {
			return 1;
		} 
		else {
			
			if(this.math > s.math) {
				return -1;
			} 
			else {
				return 1;
			}
		}
	}
}

StringTokenizer類

將字串分解成可被獨立使用的單詞時,可以使用java.util包中的StringTokenizer類,該類有兩個常用的構造方法:

StringTokenizer(String s) 為字串s構造一個分析器。使用預設的分隔符集合,即空格符(若干個空格被看做一個空格)、換行符、回車符、Tab符、進紙符

StringTokenizer(String s, String delim) 為字串s構造一個分析器。引數delim中的字元被作為分隔符

主要方法:

當呼叫nextToken()時,都將在字串中獲得下一個語言符號,同時,字串分析器中的負責計數的變數的值就自動減一;

hasMoreTokens(),只要字串中還有語言符號,返回true,否則為false;

countTokens(),得到分析器中計數變數的值

{  public static void main(String args[])
   {  String s="I am James,she is my girlfriend";
      StringTokenizer fenxi=new StringTokenizer(s,“ ,”);   //空格和逗號分隔
      int number=fenxi.countTokens();
      while(fenxi.hasMoreTokens()) 
       {  String str=fenxi.nextToken();
          System.out.println(str);
          System.out.println("還剩"+fenxi.countTokens()+"個單詞");
       }
     System.out.println("s共有單詞:"+number+"個");
   } 

字串與字元、位元組陣列

public void getChars(int start,int end,char c[],int offset ) :字串呼叫getChars方法將當前字串中的一部分字元複製到引數c指定的陣列中。將字串中從位置start到end-1位置上的字元複製的陣列c中,並從陣列c的offset處開始存放這些字元。需要注意的是,必須保證陣列c能容納下要被複製的字元。

public char[] toCharArray() :字串物件呼叫該方法可以初始化一個字元陣列,該陣列的長度與字串的長度相等,並將字串物件的全部字元複製到該陣列中。

String s;
String[] c = new String[2];
s.getChar(0,2,c,0);


StringBuffer類

String類建立的字串物件是不可修改的,也就是說,String字串不能修改、刪除或替換字串中的某個字元,即String物件一旦建立,那麼實體是不可以再發生變化的.

StringBuffer類能建立可修改的字串序列,也就是說,該類的物件的實體的記憶體空間可以自動的改變大小,便於存放一個可變的字元序列。

StringBuffer() 無引數建立StringBuffer物件,初始容量為16個;

StringBuffer(int size) 初始容量為size個字元;

StringBuffer(String s) 初始容量為字串s的長度額外再加16字元。

常用方法:

Append() 可將其他Java型別資料轉化為字串後再追加到StringBuffer物件中;

char charAt (int n) 得到第n個位置上的字元;

void setCharAt (int n, char ch) 將第n個位置上的字元用ch指定的字元替換;

StringBuffer insert (int index, String str)將一個字串str插入到第index位置上,並返回當前物件的引用;

public StringBuffer reverse() 將字元序列翻轉;

StringBuffer delete (int startIndex, int endIndex) 刪除從startIndex開始到endIndex-1的子串;

StringBuffer replace( int startIndex, int endIndex, String str) 將從startIndex開始到endIndex-1的子串用字串str替換。
public static void main(String args[]) {
		StringBuffer str = new StringBuffer("62791720");
		str.insert(0, "010-");
		System.out.println(str);
		str.setCharAt(7, '8');
		System.out.println(str);
		str.setCharAt(str.length() - 1, '7');
		System.out.println(str);
		str.append("-446");
		System.out.println(str);
		str.reverse();
		System.out.println(str);
	}
//輸出:
/*010-62791720
  010-62781720
  010-62781727
  010-62781727-446
  644-72718726-010*/

StringBuilder類

異常

介紹

在編寫程式時,經常要在可能出現錯誤的地方加上檢測的 程式碼,如進行x/y運算時,要檢測分母為0,資料為空,輸 入的不是資料而是字元等。過多的if-else分支會導致程式 的程式碼加長、臃腫,可讀性差。因此採用異常處理機制。

在 Java 中一個異常的產生,主要有如下三種原因:

  1. Java 內部錯誤發生異常,Java 虛擬機器產生的異常。
  2. 編寫的程式程式碼中的錯誤所產生的異常,例如空指標異常、陣列越界異常等。
  3. 透過 throw 語句手動生成的異常,一般用來告知該方法的呼叫者一些必要資訊。

我們把生成異常物件,並把它提交給執行時系統的過程稱為丟擲(throw)異常。

Java採用的異常處理機制,是將異常處理的程式程式碼集中 在一起,與正常的程式程式碼分開,使得程式簡潔、優雅, 並易於維護。

異常的根類 是java.lang.Throwable。其下有兩個子類: java.lang.Exception與java.lang.Error,平常所說的異 常指java.lang.Exception。

img

執行時異常和非執行時異常也稱為 不檢查異常檢查異常

  • Exception 類用於使用者程式可能出現的異常情況,它也是用來建立自定義異常型別類的類。
  • Error 定義了在通常環境下不希望被程式捕獲的異常。一般指的是 JVM 錯誤,如堆疊溢位。

討論Exception型別異常:

執行時異常都是 RuntimeException 類及其子類異常,如 NullPointerException、IndexOutOfBoundsException 等,這些異常是不檢查異常,程式中可以選擇捕獲處理,也可以不處理。這些異常一般由程式邏輯錯誤引起,程式應該從邏輯角度儘可能避免這類異常的發生。

非執行時異常是指 RuntimeException 以外的異常,型別上都屬於 Exception 類及其子類。從程式語法角度講是必須進行處理的異常,如果不處理,程式就不能編譯透過。如 IOException、ClassNotFoundException 等以及使用者自定義的 Exception 異常(一般情況下不自定義檢查異常)。

Java中常見執行時異常RunTimeException

異常型別 說明
ArithmeticException 算術錯誤異常,如以零做除數
ArraylndexOutOfBoundException 陣列索引越界
ArrayStoreException 向型別不相容的陣列元素賦值
ClassCastException 型別轉換異常
IllegalArgumentException 使用非法實參呼叫方法
lIIegalStateException 環境或應用程式處於不正確的狀態
lIIegalThreadStateException 被請求的操作與當前執行緒狀態不相容
IndexOutOfBoundsException 某種型別的索引越界
NullPointerException 嘗試訪問 null 物件成員,空指標異常
NegativeArraySizeException 再負數範圍內建立的陣列
NumberFormatException 數字轉化格式異常,比如字串到 float 型數字的轉換無效
TypeNotPresentException 型別未找到

Java常見非執行時異常

異常型別 說明
ClassNotFoundException 沒有找到類
IllegalAccessException 訪問類被拒絕
InstantiationException 試圖建立抽象類或介面的物件
InterruptedException 執行緒被另一個執行緒中斷
NoSuchFieldException 請求的域不存在
NoSuchMethodException 請求的方法不存在
ReflectiveOperationException 與反射有關的異常的超類

Java中Error和Exception的異常同

Error(錯誤)和 Exception(異常)都是 java.lang.Throwable 類的子類,在 Java 程式碼中只有繼承了 Throwable 類的例項才能被 throw 或者 catch。

Exception 是程式正常執行過程中可以預料到的意外情況,並且應該被開發者捕獲,進行相應的處理。

Error 是指正常情況下不大可能出現的情況,絕大部分的 Error 都會導致程式處於非正常、不可恢復狀態。所以不需要被開發者捕獲。Error錯誤是任何處理技術都無法恢復的情況,肯定會導致程式非正常終止。且屬於未檢查型別。

Exception又可分為可檢查(checked)異常和不檢查(unchecked)異常。

可檢查異常在原始碼裡必須顯示的進行捕獲處理,治理是編譯期檢查的一部分。

不檢查異常就是所謂的執行時異常,通常是可以編碼避免的邏輯錯誤,具體根據需要來判斷是否需要捕獲,並不會在編譯器強制要求。

  1. 執行時異常(RuntimeException):
    1. NullPropagation:空指標異常:
    2. ClassCastException:型別強制轉換異常
    3. IllegalArgumentException:傳遞非法引數異常
    4. IndexOutOfBoundsException:下標越界異常
    5. NumberFormatException:數字格式異常
  2. 非執行時異常:
    1. ClassNotFoundException:找不到指定class的異常
    2. IOException:IO操作異常
  3. 錯誤(Error):
    1. NoClassDefFoundError:找不到class定義異常
    2. StackOverflowError:深遞迴導致棧被耗盡而丟擲的異常
    3. OutOfMemoryError:記憶體溢位異常

宣告異常——>丟擲異常——>捕獲異常

異常處理機制:

Java的異常處理透過5個關鍵字來實現:try、catch、throw和finally。

try catch語句用於捕獲並處理異常,finally語句用於在任何情況下(除特殊情況外)都必須執行的程式碼,throw語句用於丟擲異常,throws語句用於宣告可能會出現的異常。

異常處理的機制機制如下:

  • 在方法中用try catch 語句捕獲並處理異常,catch語句可以有多個,用來匹配多個異常。
  • 對於處理不了的異常或者要轉型的異常,在方法的宣告處透過throws語句丟擲異常,即由上層的呼叫方法來處理。
try{
    邏輯程式塊
} catch(ExceptionTyple1 e){
    處理程式碼塊1
} catch(ExceptionTyple2 e){
    處理程式碼塊2
        throw(e);//再丟擲這個“異常”
} finally{
    釋放資原始碼塊
}

在多個 catch 程式碼塊的情況下,當一個 catch 程式碼塊捕獲到一個異常時,其它的 catch 程式碼塊就不再進行匹配。

try catch finally執行順序

僅僅在下面4中情況下不會執行finally語句 :

①.如果在try 或catch語句中執行了System.exit(0)。

②.在執行finally之前jvm崩潰了。

③.try語句中執行死迴圈。

④.電源斷電

①、不管有沒有出現異常,finally塊中程式碼都會執行;

  public void demo1(){
        try {

          System.out.println(result);

        } catch (Exception e) {                     
            System.out.println(e.getMessage());
        }
         finally {            
                System.out.println("finally trumps. ");
            }
//輸出結果為:
result
finally trumps .

②、當try和catch中有return時,finally仍然會執行;

public static int demo2() {
        try {
            return 0;
        }
        finally {
            System.out.println("finally trumps return.");
        }
    }
//輸出結果

finally trumps return.
0   
    //當finally裡面沒有return語句是,執行try 和finally語句之後最後再執行return。

③、finally是在return後面的表示式運算後執行的(此時並沒有返回運算後的值,而是先把要返回的值儲存起來,管finally中的程式碼怎麼樣,返回的值都不會改變,任然是之前儲存的值),所以函式返回值是在finally執行前確定的;

public static int demo3()
    {
         int i = 0;
            try {
                i = 2;
                return i;
            } finally {
                i = 12;
                System.out.println("finally trumps return.");
            }       
    }
//輸出結果
    finally trumps return.
    2
//執行前的值
此處中finally中對i賦值12但是demo3的返回值仍然是2,也就是在finally中對i賦值並未改變i的返回值
        

④、finally中最好不要包含return,否則程式會提前退出,返回值不是try或catch中儲存的返回值。

    public static int demo4() {
        int i = 0;
        try {
            return i;
        } finally {
            i = 12;
            System.out.println("finally trumps return.");
            return i;
        }
    }
    //輸出結果
    finally trumps return.
    12  
        上面為什麼會返回12呢?因為在程式還未執行try中的return語句時就先執行了finally裡面的return語句所以返回結果為12。
  • 可以有多個catch塊,並且try塊後面,只能有1個或1個finally塊。

  • try塊後面,如果沒有catch塊,則後面必須有一個finally

public static void main(String[] args) {
    try {
        System.out.println("try...");
    }
    finally {
        System.out.println("finally...");
    }
}

//輸出結果:
//try...
//finally...

  • 執行程式碼捕獲異常後,進入catch塊,try中出現異常程式碼後面的程式碼不會在繼續執行
  • 當try塊中或者catch塊中遇到return語句時,先執行完finally裡面的程式碼後,再執行return返回語句
public static void main(String[] args) {
    try {
        System.out.println("try...");
        return;
    } catch (ArithmeticException e) {
        System.out.println("ArithmeticException...");
    } catch (NullPointerException e) {
        System.out.println("NullPointerException...");
    } finally {
        System.out.println("finally...");
    }
}

//輸出結果:
//try...
//finally...

throws 和 throw:宣告和丟擲異常

Java 中的異常處理除了捕獲異常和處理異常之外,還包括宣告異常和丟擲異常。實現宣告和丟擲異常的關鍵字非常相似,它們是 throws 和 throw。可以透過 throws 關鍵字在方法上宣告該方法要丟擲的異常,然後在方法內部透過 throw 丟擲異常物件。

throws宣告異常

當一個方法產生一個它不處理的異常時,那麼就需要在該方法的頭部宣告這個異常,以便將該異常傳遞到方法的外部進行處理。使用 throws 宣告的方法表示此方法不處理異常。throws 具體格式如下:

returnType method_name(paramList) throws Exception 1,Exception2,…{…}

如果有多個異常類,它們之間用逗號分隔。這些異常類可以是方法中呼叫了可能丟擲異常的方法而產生的異常,也可以是方法體中生成並丟擲的異常。

使用 throws 宣告丟擲異常的思路是,當前方法不知道如何處理這種型別的異常,該異常應該由向上一級的呼叫者處理;如果 main 方法也不知道如何處理這種型別的異常,也可以使用 throws 宣告丟擲異常,該異常將交給 JVM 處理。JVM 對異常的處理方法是,列印異常的跟蹤棧資訊,並中止程式執行,這就是前面程式在遇到異常後自動結束的原因。

import java.io.FileInputStream;
import java.io.IOException;
public class Test04 {
    public void readFile() throws IOException {
        // 定義方法時宣告異常
        FileInputStream file = new FileInputStream("read.txt"); // 建立 FileInputStream 例項物件
        int f;
        while ((f = file.read()) != -1) {
            System.out.println((char) f);
            f = file.read();
        }
        file.close();
    }
    public static void main(String[] args) {
        Throws t = new Test04();
        try {
            t.readFile(); // 呼叫 readFHe()方法
        } catch (IOException e) {
            // 捕獲異常
            System.out.println(e);
        }
    }
}以上程式碼,首先在定義 readFile() 方法時用 throws 關鍵字宣告在該方法中可能產生的異常,然後在 main() 方法中呼叫 readFile() 方法,並使用 catch 語句捕獲產生的異常。

方法重寫時宣告丟擲異常的限制

使用 throws 宣告丟擲異常時有一個限制,是方法重寫中的一條規則:子類方法宣告丟擲的異常型別應該是父類方法宣告丟擲的異常型別的子類或相同,子類方法宣告丟擲的異常不允許比父類方法宣告丟擲的異常多。看如下程式。

public class OverrideThrows {//父類
    public void test() throws IOException {
        FileInputStream fis = new FileInputStream("a.txt");
    }
}
class Sub extends OverrideThrows {//子類
    
    // 子類方法宣告丟擲了比父類方法更大的異常
    // 所以下面方法出錯
    public void test() throws Exception {
    }Exception比它的父類大
}
錯誤!!!
    
   
所以在編寫類繼承程式碼時要注意,子類在重寫父類帶 throws 子句的方法時,子類方法宣告中的 throws 子句不能出現父類對應方法的 throws 子句中沒有的異常型別,因此 throws 子句可以限制子類的行為。也就是說,子類方法丟擲的異常不能超過父類定義的範圍。  

對於自定義類throws的使用,在main中的使用方法

 public static void main(String[] args) {
        // TODO Auto-generated method stub
       int result = divide(4,2);
       System.out.println(result);
    }
    public static int divide(int x,int y) throws Exception
    {
        int result = x/y;
        return result;
    }
這樣是錯誤的,需要在main中使用throws 或者try catch語句
    public static void main(String[] args) {
        
      try {
         int    result = divide(4,2);
          System.out.println(result);
       } catch (Exception e) {
        
          e.printStackTrace();
       }
      
    }
=======或者
    public static void main(String[] args) throws Exception {
          int    result = divide(4,0);
          System.out.println(result);
    }

throw丟擲異常

與 throws 不同的是,throw 語句用來直接丟擲一個異常,後接一個可丟擲的異常類物件,其語法格式如下:

throw ExceptionObject;

其中,ExceptionObject 必須是 Throwable 類或其子類的物件。如果是自定義異常類,也必須是 Throwable 的直接或間接子類。例如,以下語句在編譯時將會產生語法錯誤:

throw new String("丟擲異常");    // String類不是Throwable類的子類
package Collection排序;

import java.util.Scanner;

public class Test05 {
	public boolean validateUserName(String username){
		boolean con = false;
		if(username.length() > 8) {
			for(int i = 0; i < username.length(); i++) {
				char ch = username.charAt(i);
				if( ch >= '0' && ch <= '9' || ch >= 'a' && ch <='z' || ch > 'A' && ch <= 'Z') {
					con = true;
				} else {
					con = false;
					throw new IllegalArgumentException("使用者長度必須由字母和數字組成!");
				}
			}
			
		}else {
			throw new IllegalArgumentException("使用者長度必須大於8位");
		}
		return con;
	}
	public static void main(String[] args){
		Test05 te = new Test05();
		Scanner input = new Scanner(System.in);
		System.out.println("請輸入使用者名稱:");
		String username = input.next();
		try {
			boolean con = te.validateUserName(username);
			if(con) {
				System.out.println("使用者輸入正確");
			}
		} catch(IllegalArgumentException e){
			System.out.println(e);
		}
	}
}

!!throw單獨存在,下面不要定義語句,因為執行不到

public class Test05 {
	public static void func() {
		try {
			throw new Exception();
		} catch (Exception e) {
			System.out.println("B");
		}
	}

	public static void main(String[] args) {
		try {
			func();
		} catch (Exception e) {
			System.out.println("C");
		}
		System.out.println("D");
	}
}
輸出:
    B
    D
    

throw new 語句的執行順序

package Collection排序;

import java.util.Scanner;

public class Test05 {
	static void methodA() {
		try {
			System.out.println("進入方法A");
			throw new RuntimeException("製造異常");
            //先執行finall語句,在執行 throw的語句
		} finally {
			System.out.println("用A方法的finally");
		}
	}

	static void methodB() {
		try 
		{
		System.out.println(
		"進入方法B");
		return;
		} finally 
		{
		System.out.println(
		"呼叫B方法的finally");
		}
		}

	public static void main(String[] args) {
		try {
			methodA();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		methodB();
	}

}

子類繼承父類異常

子類的丟擲範圍不能大於父類,但若父類異常是IOException,子類是RunTimeException,這種情況是可以的。

輸入輸出流

Java中所有資料都是使用流讀寫的。流是以組有序的資料序列,將資料從一個地方帶到另一個地方。根據資料流向的不同,可以分為輸入(input)流和輸出(output)流兩種。

輸入就是將資料從各種輸入裝置(包括檔案、鍵盤等)中讀取到記憶體中,輸出則正好相反,是將資料寫入到各種輸出裝置(比如檔案、顯示器、磁碟等)。例如鍵盤就是一個標準的輸入裝置,而顯示器就是一個標準的輸出裝置,但是檔案既可以作為輸入裝置,又可以作為輸出裝置。

資料流是 Java 進行 I/O 操作的物件,它按照不同的標準可以分為不同的類別。

  • 按照流的方向主要分為輸入流和輸出流兩大類。
  • 資料流按照資料單位的不同分為位元組流和字元流。
  • 按照功能可以劃分為節點流和處理流。

資料流的處理只能按照資料序列的順序來進行,即前一個資料處理完之後才能處理後一個資料。資料流以輸入流的形式被程式獲取,再以輸出流的形式將資料輸出到其它裝置。

image-20221126192159575

輸入流

Java 流相關的類都封裝在 java.io 包中,而且每個資料流都是一個物件。所有輸入流類都是 InputStream 抽象類(位元組輸入流)和 Reader 抽象類(字元輸入流)的子類。其中 InputStream 類是位元組輸入流的抽象類,是所有位元組輸入流的父類,其層次結構如圖 3 所示。

InputStream類的層次結構圖

InputStream 類中所有方法遇到錯誤時都會引發 IOException 異常

名稱 作用
int read() 從輸入流讀入一個 8 位元組的資料,將它轉換成一個 0~ 255 的整數,返回一個整數,如果遇到輸入流的結尾返回 -1
int read(byte[] b) 從輸入流讀取若干位元組的資料儲存到引數 b 指定的位元組陣列中,返回的位元組數表示讀取的位元組數,如果遇到輸入流的結尾返回 -1
int read(byte[] b,int off,int len) 從輸入流讀取若干位元組的資料儲存到引數 b 指定的位元組陣列中,其中 off 是指在陣列中開始儲存資料位置的起始下標,len 是指讀取位元組的位數。返回的是實際讀取的位元組數,如果遇到輸入流的結尾則返回 -1
void close() 關閉資料流,當完成對資料流的操作之後需要關閉資料流
int available() 返回可以從資料來源讀取的資料流的位數。
skip(long n) 從輸入流跳過引數 n 指定的位元組數目
boolean markSupported() 判斷輸入流是否可以重複讀取,如果可以就返回 true
void mark(int readLimit) 如果輸入流可以被重複讀取,從流的當前位置開始設定標記,readLimit 指定可以設定標記的位元組數
void reset() 使輸入流重新定位到剛才被標記的位置,這樣可以重新讀取標記過的資料

輸出流

在 Java 中所有輸出流類都是 OutputStream 抽象類(位元組輸出流)和 Writer 抽象類(字元輸出流)的子類。其中 OutputStream 類是位元組輸出流的抽象類,是所有位元組輸出流的父類,其層次結構如圖 4 所示。

OutputStream類的層次結構圖

OutputStream 類是所有位元組輸出流的超類,用於以二進位制的形式將資料寫入目標裝置,該類是抽象類,不能被例項化。OutputStream 類提供了一系列跟資料輸出有關的方法,如下所示。

名稱 作用
int write(b) 將指定位元組的資料寫入到輸出流
int write (byte[] b) 將指定位元組陣列的內容寫入輸出流
int write (byte[] b,int off,int len) 將指定位元組陣列從 off 位置開始的 len 位元組的內容寫入輸出流
close() 關閉資料流,當完成對資料流的操作之後需要關閉資料流
flush() 重新整理輸出流,強行將緩衝區的內容寫入輸出流

檢視系統預設編碼

public class Test05 {
	public static void main(String[] args) {
		System.out.println(System.getProperty("file.encoding"));
	}
}

程序Java File類(檔案操作類)詳解 (biancheng.net)

相關文章