天天看點

Java第四周總結

第四後總結中的大部分知識點内容我之前都發過,這隻是我的一個總結。

1. 集合

1.1 為什麼使用集合

開發中會使用大量相同資料類型的情況。如果使用數組來解決問題

1. 數組能夠使用的方法非常少,功能方法需要程式員自己完成。

2. 資料類型單一化,不支援多種情況。

3. 數組容量不可以更改。

集合為解決問題而生:

1. 方法多種多樣,基本功能完善

2. 資料類型支援多樣化,但是又不失資料類型一緻要求

3. 容量可以變,并且不用開發者操心

1.2 集合架構

Java中集合的【總接口】Collection。Java中所有和集合有關的内容,都是Collection接口的子接口或者實作類

interface Collection

–| interface List List接口,有序可重複

----| class ArrayList

【重點】可變長數組結構

原碼實作,了解其中的特征,性能…

----| class LinkedList

【重點】雙向連結清單結構

----| class Vector

【遠古時代】JDK1.0 線程安全的ArrayList,如果不考慮線程安全問

題,建議使用ArrayList

–| interface Set Set接口,無序不可重複

----| HashSet 底層存儲資料的方式是采用哈希表方式

----| TreeSet 底層存儲資料的方式一個平衡二叉樹方式

以上這些東西我們之後會一一講解,現在我們先來了解一下collection接口的常用方法

1.3 Collection<E>接口下的常用方法

增:

boolean add(E e);

存入元素到目前集合對象中,這裡要求的資料類型是E類型,也就是泛型對于

的具體資料類型

boolean addAll(Collection<? extends E> c);

class Dog extends Animal

class Cat extends Animal

class Tiger extends Animal

==> ? extends E 泛型的上限

要求存入的集合c中,存儲的元素要麼是E類型,要麼是E類的子類

删:

void clear();

清空整個集合

boolean remove(Object obj);

删除集合中的指定元素

boolean removeAll(Collection<?> c);

删除兩個集合的交集

boolean retainAll(Collection<?> c);

保留兩個集合的交集

查:

int size();

傳回集合中有效元素個數

boolean isEmpty();

判斷目前集合是否為空

boolean contains(Object obj);

判斷指定元素在目前集合中是否存在

boolean containsAll(Collection<?> c);

判斷集合c是不是目前集合的子集合

以下是代碼的實作:

注意導包,之前的部分代碼也需要導包

就是這個:

import java.util.ArrayList;

import java.util.Collection;

public class Demo1 {
	public static void main(String[] args) {
		/*
		 * 因為Collection<E>是一個接口,接口沒有自己的類對象
		 * 這裡使用Collection接口的實作類來完成示範過程 ArrayList<E>
		 */
		Collection<String> c = new ArrayList<String>();
		
		c.add("82年的拉菲");
		c.add("82年的雪碧");
		c.add("82年的可樂");
		c.add("82年的老雪");
		
		System.out.println(c);
		
		Collection<String> c1 = new ArrayList<String>();
		
		c1.add("百威");
		c1.add("福佳白");
		c1.add("精釀啤酒");
		c1.add("修道院啤酒");
		
		c.addAll(c1);
		
		System.out.println(c);
		
		c.remove("82年的雪碧");
		System.out.println(c);
		
		//c.removeAll(c1);
		//System.out.println(c);
		
		//c.retainAll(c1);
		//System.out.println(c);
		
		System.out.println("size:" + c.size());
		System.out.println(c.isEmpty());
		
		System.out.println(c.contains("百威"));
		System.out.println(c.contains("哈爾濱"));
		
		System.out.println(c.containsAll(c1));
		
		c1.add("野格");
		System.out.println(c.containsAll(c1));
	}
}           

複制

1.4 疊代器

通過集合對象擷取對應的Iterator疊代器

Iterator iterator();

常用方法:

boolean hasNext();

判斷目前Iterator是否可以繼續運作。

E next();

擷取Iterator目前指向元素,并且指向下一個元素。

void remove();

删除

【注意】

1. remove方法有且隻能删除通過next方法擷取的元素

2. remove方法如果想要使用,必須緊挨着next方法

代碼實作:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Demo1 {
	public static void main(String[] args) {
		Collection<String> c = new ArrayList<String>();
		
		c.add("星期一");
		c.add("星期二");
		c.add("星期三");
		c.add("星期四");
		c.add("星期五");
		c.add("星期六");
		c.add("星期日");
		
		System.out.println(c);
		
		/*
		 * 擷取目前集合對應的Iterator疊代器對象
		 */
		Iterator<String> iterator = c.iterator();
		/*
		System.out.println("目前Iterator是否可以繼續運作:" +iterator.hasNext());
		System.out.println("擷取當Iterator指向元:" + iterator.next());
		System.out.println("擷取當Iterator指向元:" + iterator.next());
		
		iterator.remove();
		System.out.println(c);
		iterator.remove();
		System.out.println(c);
		*/
		
		while (iterator.hasNext()) {
			iterator.next();
			iterator.remove();
		}
		
		System.out.println(c.isEmpty());
		
		
	}
}           

複制

1.5 Iterator使用注意問題

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Demo2 {
	public static void main(String[] args) {
		ArrayList<String> c = new ArrayList<String>();

		c.add("烤羊排");
		c.add("油焖大蝦");
		c.add("洋芋牛肉");
		c.add("黃焖雞米飯");
		c.add("麻辣香鍋");
		c.add("孜然肉片");
		c.add("酸湯肥牛");
		
		Iterator<String> iterator = c.iterator();
		
		/*
		 * ConcurrentModificationException
		 * Iterator在建立的過程中,會對整個集合所有元素打招呼,記錄每一個元素位置。
		 * Iterator在執行next方法過程中,會按照初始條件一個一個周遊
		 * 目前集合通過remove方法,删除已經被Iterator記錄的元素時,是有可能導緻
		 * Iterator一臉懵逼!!!元素不見了!!!
		 * 
		 * 這裡就會發生沖突!
		 * 
		 * 這裡因為集合中元素,對于集合本身和目前Iterator而言是一個共享資源
		 * 不管是哪一方操作元素,都存在影響對方操作的情況。【共享資源沖突問題】
		 * 
		 * ArrayList存儲元素不是連續的嗎,洋芋牛肉删除了,他的位置不是會被後面的元素頂上來嗎

		 */
		while (iterator.hasNext()) {
			System.out.println(iterator.next());
			
			// 這裡通過集合删除洋芋牛肉元素
			// 後期代碼中會出現很多相同名字方法,這裡一定要注意!!!
			// 調用目前方法的是哪一個
			c.remove("酸湯肥牛");
		}
	}
}           

複制

Iterator出現并發錯誤原因:

Java第四周總結

1.6 List<E>

1.6.1 List集合接口特征和方法

特征:

有序,可重複

有序: 添加順序和存儲順序一緻

可重複:相同元素可以同時添加

List接口下的實作類,存在一定的下标操作機制

ArrayList 底層數組形式操作,可以通過下标直接通路

LinkedList 底層是一個雙向連結清單結構,下标 ==> 計數器

特定的方法:

增:

add(E e);

List接口下,目前方法是添加元素到集合的末尾,尾插法

addAll(Collection<? extends E> c);

List接口下,目前方法是添加另一個集合到目前集合末尾,要求添加的

集合中儲存的元素和目前集合儲存元素一緻,或者說是目前集合儲存元

素的子類

add(int index, E e);

在指定的下标位置,添加指定元素

addAll(int index, Collection<? extends E> c);

在指定的下标位置,添加指定的集合,集合要求同上一個addAll方法

删:

void clear();

清空整個集合

remove(Object obj);

删除集合中的指定元素

removeAll(Colletion<?> c);

删除兩個集合的交集

retainAll(Colletion<?> c);

保留兩個集合的交集

E remove(int index);

删除集合中指定下标的元素。傳回值是被删除的元素

改:

E set(int index, E e);

使用指定元素替換指定下标index的元素,傳回值是被替換掉的元素。

查:

int size();

有效元素個數

boolean isEmpty();

判斷目前集合是否為空

boolean contains(Object obj);

boolean containsAll(Collection<?> c);

int indexOf(Object obj);

找出指定元素在集合中的第一次出現位置

int lastIndexOf(Object obj);

找出指定元素在集合中最後一次出現位置

E get(int index);

擷取指定下标的元素

List subList(int fromIndex, int endIndex);

擷取目前集合的子集合

【特征】

擷取資料的範圍是 fromIndex <= n < endIndex

要頭不要尾

1.7 ArrayList 可變長數組

特征:

數組形式的操作方式,查詢效率高,但是删除,增加效率低。

數組:

Object類型數組

方法:

ArrayList使用的方法基本上都是從List接口中遵從實作的方法。

特征:

ensureCapacity(int minCapacity);

判斷目前容量是否足夠

trimToSize();

截斷整個數組容量 ==> size有效元素個數

時間換空間,空間換時間

自定義實作的ArrayList

Constructor構造方法

add(E e);

add(int index, E e);

addAll(自定義ArrayList e)

addAll(int index,自定義ArrayList e)

remove(Object obj);

remove(int index);

set(int index, E);

E get(int index);

int indexOf();

int lastIndexOf();

boolean contains(Object obj);

boolean containsAll(自定義ArrayList類型 list)

boolean isEmpty();

int size();

自定義ArrayList subList(int fromIndex, int endIndex);

Object[] toArray();

方法代碼實作:

import java.util.Arrays;

/**
 * 自定義實作MyArraylist
 * @author Anonymous
 *
 * @param <E> 自定義泛型
 */
public class MyArrayList<E> {
	/**
	 * 準備一個底層數組,用于存儲資料内容
	 */
	private Object[] elements;
	
	/**
	 * 初始化預設容量
	 */
	private static final int DEFAULT_CAPACITY = 10;
	
	/**
	 * 最大數組容量, -8是為了騰出一定的空間,儲存數組的必要内容
	 */
	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
	
	/**
	 * 目前底層數組中儲存的有效元素個數
	 */
	private int size = 0;
	
	/**
	 * 無參數構造方法,但是需要提供給使用者一個初始化容量來儲存必要的資料
	 */
	public MyArrayList() {
		elements = new Object[DEFAULT_CAPACITY];
	}
	
	/**
	 * 使用者指定儲存元素容量的初始化過程,要求使用者指定的容量範圍是有效的
	 * 
	 * @param initCapacity 使用者指定的初始化容量,但是不能小于等于0 ,不能大于
	 * 						MAX_ARRAY_SIZE
	 */
	public MyArrayList(int initCapacity) {
		// 使用者傳入參數的合法性判斷過程
		if (initCapacity < 0 || initCapacity > MAX_ARRAY_SIZE) {
			// 抛出異常
			// IllegalArgumentException 是一個RuntimeException運作時異常的子類
			// 不需要強制聲明抛出異常
			throw new IllegalArgumentException("IllegalArgumentException : " + initCapacity);
		}
		
		elements = new Object[initCapacity];
	}
	
	/*
	 * 增加方法
	 */
	/**
	 * 添加元素到目前集合的末尾
	 * 
	 * @param e 要求是符合泛型限制的指定資料類型
	 * @return 添加成功傳回true, 否則傳回false
	 */
	public boolean add(E e) {
		// 直接調用在指定下标位置添加元素的方法,隻不過這裡指定下标位置就是
		// 尾插法下标位置
		return add(size, e);
	}
	
	/**
	 * 在底層數組的指定下标位置儲存對應的元素
	 * 
	 * @param index 指定下标位置,不能超出有效範圍,0<= index <= size
	 * @param e 符合泛型限制的資料類型
	 * @return 添加成功傳回true, 否則傳回false
	 */
	public boolean add(int index, E e) {
		if (index < 0 || index > size) {
			throw new ArrayIndexOutOfBoundsException(index);
		}
		
		ensureCapacity(size + 1);
		
		for (int i = size; i > index; i--) {
			elements[i] = elements[i - 1];
		}
		
		elements[index] = e;
		size += 1;
		
		return true;
	}
	
	/*
	 * addAll方法
	 * 		1. 需要得到添加集合中元素内容,有效元素個數
	 * 		2. 确認容量問題
	 * 		3. size = srcSize + newSize
	 */
	/**
	 * 添加另一個集合到目前集合的末尾
	 * 
	 * @param list MyArrayList類型,自定義ArrayList,要求存儲元素和目前集合一緻,或者
	 * 				是其子類
	 * @return 添加成功傳回true,添加失敗傳回false
	 */
	public boolean addAll(MyArrayList<? extends E> list) {
		Object[] array = list.toArray();
		int newSize = array.length;
		
		ensureCapacity(size + newSize);
		
		for (int i = 0; i < newSize; i++) {
			elements[i + size] = array[i];
		}
		
		size += newSize;
		return true;
	}
	
	/**
	 * Do yourself 作業
	 * @param index
	 * @param list
	 * @return
	 */
	public boolean addAll(int index, MyArrayList<? extends E> list) {
		return true;
	}
	
	/**
	 * 删除指定元素 
	 * 
	 * @param obj 指定删除的元素
	 * @return 删除成功傳回true
	 */
	public boolean remove(Object obj) {
		int index = indexOf(obj);
		
		return null != remove(index);
	}
	
	/**
	 * 删除下标元素
	 * 
	 * @param index 指定的下标範圍
	 * @return 删除成功傳回對應元素,失敗傳回null
	 */
	public E remove(int index) {
		if (-1 == index) {
			return null;
		}
		
		E e = get(index);
		
		for (int i = index; i < size - 1; i++) {
			elements[i] = elements[i + 1];
		}
		
		// 原本最後一個有效元素位置上的内容指派為null
		elements[size - 1] = null;
		size -= 1;
		
		return e;
	}
	
	/**
	 * 擷取集合中指定下标的元素
	 * 
	 * @param index 指定下标的範圍,但是不能超出有效下标範圍
	 * @return 傳回對應的元素
	 */
	@SuppressWarnings("unchecked")
	public E get(int index) {
		if (index < 0 || index > size) {
			throw new ArrayIndexOutOfBoundsException(index);
		}
		
		return (E) elements[index];
	}
	
	/**
	 * 查詢指定元素在集合中的第一次出現下标位置
	 * @param obj 指定的元素
	 * @return 傳回值大于等于0表示找到元素,否則傳回-1
	 */
	public int indexOf(Object obj) {
		int index = -1;

		for (int i = 0; i < size; i++) {
			// equals 判斷對象是否一緻地方的方法
			if (obj.equals(elements[i])) {
				index = i;
				break;
			}
		}
		
		return index;
	}
	
	/**
	 * 查詢指定元素在集合中的最後一次出現下标位置
	 * 
	 * @param obj 指定的元素
	 * @return 傳回值大于等于0表示找到元素,否則傳回-1
	 */
	public int lastIndexOf(Object obj) {
		int index = -1;

		for (int i = size - 1; i >= 0; i--) {
			// equals 判斷對象是否一緻地方的方法
			if (obj.equals(elements[i])) {
				index = i;
				break;
			}
		}
		
		return index;
	}
	
	/**
	 * 傳回MyArrayList集合中所有有效元素的Object數組
	 * 
	 * @return 包含所有集合元素的Object類型數組
	 */
	public Object[] toArray() {
		// size是有效元素個數,通過該方法可以擷取到一個隻有目前數組中有效元素的數組
		return Arrays.copyOf(elements, size);
	}
	
	
	/**
	 * 替換指定下标的元素
	 * 
	 * @param index 指定下标元素,但是必須在有效範圍以内
	 * @param e 符合泛型限制的對應資料類型
	 * @return 被替換的元素
	 */
	public E set(int index ,E e) {
		if (index < 0 || index >= size) {
			throw new ArrayIndexOutOfBoundsException(index);
		}
		
		E temp = get(index);
		elements[index] = e;
		
		return temp;
	}
	
	/**
	 * 判斷指定元素是否存在 
	 * 
	 * @param obj 指定元素
	 * @return 存在傳回true,不存在傳回false
	 */
	public boolean contains(Object obj) {
		return indexOf(obj) > -1; 
	}
	
	/**
	 * 
	 * @param list
	 * @return
	 */
	public boolean containsAll(MyArrayList<?> list) {
		return false;
	}
	
	/**
	 * 判斷集合是否是空的
	 * 
	 * @return 如果為空,傳回true, 否則傳回false
 	 */
	public boolean isEmpty() {
		return size == 0;
	}
	
	/**
	 * 擷取目前集合中有效元素個數
	 * 
	 * @return 有效元素個數
	 */
    public int size() {
    	return size;
    }
    
    /**
     * 擷取目前集合的子集合,截取範圍是fromIndex <= n < endIndex
     * 
     * @param fromIndex fromIndex <= endIndex 不得小于0
     * @param endIndex endIndex >= fromIndex 小于等于size
     * @return 截取得到的一個MyArrayList子集合對象
     */
    public MyArrayList<E> subList(int fromIndex, int endIndex) {
    	if (fromIndex > endIndex || fromIndex < 0 || endIndex > size) {
    		throw new ArrayIndexOutOfBoundsException();
    	}
    	
    	MyArrayList<E> listTemp = new MyArrayList<E>(endIndex - fromIndex);
    	
    	for (int i = fromIndex; i < endIndex; i++) {
			listTemp.add(this.get(i));
		}
    	
    	return listTemp;
    }

    @Override
    public String toString() {
    	String str = "[";
    	for (int i = 0; i < size - 1; i++) {
			str += elements[i] + ", ";
		}
    	
    	return str + elements[size - 1] + "]";
    	
    }
	/*
	 * 這裡需要類内使用的可以用于判定目前容量是否滿足添加要求的方法
	 * 如果滿足直接進入添加模式,如果不滿足,需要執行grow方法,完成
	 * 底層數組的擴容問題。
	 */
	/**
	 * 每一次添加元素,都需要進行容量判斷,如果滿足可以進行添加操作
	 * 不滿足需要制定grow方法
	 * 
	 * @param minCapacity 要求的最小容量
	 */
	private void ensureCapacity(int minCapacity) {
		if (minCapacity > elements.length) {
			// 完成一個底層數組的擴容方法
			grow(minCapacity);
		}
	}
	
	
	/**
	 * 底層數組的擴容方法,原理是建立新數組,移植資料,儲存新數組位址
	 * 
	 * @param minCapacity 要求的最小容量
	 */
	private void grow(int minCapacity) {
		// 1. 擷取原數組容量
		int oldCapacity = elements.length;
		
		// 2. 計算得到新數組容量
		int newCapacity = oldCapacity + (oldCapacity >> 1);
		
		// 3. 判斷新數組容量是否滿足要求
		if (newCapacity < minCapacity) {
			newCapacity = minCapacity;
		}
		// 新數組容量是大于允許的最大數組容量
		if (newCapacity > MAX_ARRAY_SIZE) {
			// 二次判斷minCapacity是否小于MAX_ARRAY_SIZE
			if (minCapacity < MAX_ARRAY_SIZE) {
				// 最小要求是不大于MAX_ARRAY_SIZE,代碼可以運作
				newCapacity = minCapacity;
			} else {
				throw new OutOfMemoryError("Overflow MAX_ARRAY_SIZE");
			}
		}
		
		/*
		 * 4. 使用數組工具類方法完成操作
		 * Arrays.copyOf(源資料數組,可以是任意類型,采用泛型限制, 指定的新數組容量);
		 * 		a. 根據指定的新數組容量建立對應泛型資料類型的新數組
		 *      b. 從源資料數組中拷貝内容到新數組中
		 *      c. 傳回新數組首位址
		 */
		elements = Arrays.copyOf(elements, newCapacity);
	}

}           

複制

1.8 ArrayList性能問題

增删慢

增加慢

1. 增加元素有可能出現調用grow方法,grow需要進行數組的擴容操作,操作過程中需要大

量的移動和拷貝過程,浪費時間

2. 在某一個指定位置添加元素,會導緻從指定位置開始,之後的元素整體向後移動,涉及

移動複制操作,浪費時間。

删除慢:

1. 按照ArrayList可變長數組要求,删除元素之後,之後的内容都需要整體向前移動。

查詢快

1.9 補充知識點【記憶體】

記憶體中的位址

1. 記憶體中的最小單元 位元組

2. 計算機為了記錄标記每一個位元組的記憶體,給記憶體進行了編号

3. 航海中路60号,精确查詢,唯一性

4. 計算機記憶體按照位元組,一個位元組對應一個位址,從0開始編号 到 34359738367 (32G

記憶體)

5. 計算機通過記憶體編号通路對應的記憶體,效率是非常高的!!!

6. 按照十進制表示位址編号,效果很差。 這裡引入16進制 0x0 ~ 0x7 FFFF FFFF

null到底是誰?

null ==> 0x0 記憶體中編号為0的位址

該位址受到系統保護,任何程式讀取,寫入0x0位址,系統直接殺死程式

一般用于在開發中初始化引用資料類型的變量,利用null報錯。NullPointerException

Java第四周總結

1.10 LinkedList

1.10.1 1 LinkedList特征

底層是一個雙向連結清單

鍊子 自行車鍊子 船錨 手鍊

自行車鍊子

維修很友善,前斷,後斷,連結搞定!!! 找到損壞的位置,需要一個一個來

連結清單結構

1. 增删快

2. 查詢很慢很慢很慢

  1. 存儲資料,非連續空間。
  2. 資料之間通過引用連接配接,友善周遊和使用
  3. 周遊效率較低,資料非連續空間存儲,需要通過引用跳轉過程來完成
  4. 删除插入操作效率高,但是注意位址的轉移和儲存問題。
  5. LinkedList連結清單當中的操作其實大部分都是和C語言指針一個概念
Java第四周總結
1.10.2 LinkedList需要了解的方法

LinkedList使用的方法,大部分都是從List接口中遵從實作的方法

但是有一些特征方法

addFirst(E e);

addLast(E e); ==> add(E e);

E getFirst();

E getLast();

removeFirst();

removeLast();

以上方法組合可以完堆棧隊列操作

先進後出

彈夾

addLast(E e); E getLast(); removeLast();

隊列

先進先出

addLast(E e); E getFrist(); removeFirst();

1.11 自定義完成MyLinkedList

1.11.1 節點

a. 向前的引用

b. 存儲元素的引用

c. 向後的引用

class Node {

private Node prev;

private Node next;

private Object value;

// 構造方法存儲元素,進傳入連結接

}

1.11.2 管理節點的MyLinkedList

a. 連結清單頭!!!

b. 目前連結清單中有多少個元素。

class MyLinkedList {

private Node first;

private int size;

}

要求實作的方法:

add(E e);

addFirst(E e);

addLast(E e);

E getFirst();

E getLast():

E get(int index);

removeFirst();

removeLast();

remove(int index);

remove(Object obj);

E set(int index, E);

size();

1.11.3 LinkedList實作

還需要補充的方法:

add(int index,E e);

addAll(MyLinkedList list);

addAll(int index, MyLinkedList list);

boolean isEmpty();

int indexOf(Object obj);

int lastIndexOf(Object obj);

boolean contains(Object obj);

boolean containsAll(MyLinkedList<?> list);

Object[] toArray();

1.12 Set集合

1.12.1 Set集合概述

特征:

無序,不可重複

無序:添加順序和存儲順序不一緻,【不代表有排序效果】

不可重複: 在一個Set集合中不能出現相同元素

interface Set

–| class HashSet 底層是哈希表存儲資料

–| class TreeSet 底層存儲資料是一個二叉樹

1.12.2 HashSet

底層結構

Java第四周總結
import java.util.HashSet;

public class Demo2 {
	public static void main(String[] args) {
		HashSet<Person> hashSet = new HashSet<Person>();
		
		Person p1 = new Person(1, "寝室長", 10);
		Person p2 = new Person(2, "隊長", 15);
		Person p3 = new Person(3, "宇哥", 2);
		Person p4 = new Person(4, "老康", -5);
		Person p5 = new Person(5, "港兒子", 11);
		
		/*
		 * 目前這裡兩個元素,ID一樣 ==> hashCode值是一緻,會通過底層哈希表運算
		 * 儲存到同一個單元格位置。
		 * 這裡會通過equals方法,比較兩個對象是否一緻,來決定是否能夠儲存。
		 * 如果兩個對象一緻,無法儲存。
		 * 
		 * 期望每一個哈希表單元格内儲存的資料是唯一
		 */
		Person p6 = new Person(6, "康爺", 8);
		Person p7 = new Person(6, "康牙", 10);
		
		
		hashSet.add(p4);
		hashSet.add(p6);
		hashSet.add(p3);
		hashSet.add(p5);
		hashSet.add(p2);
		hashSet.add(p1);
		hashSet.add(p7);
		
		System.out.println(hashSet);
	}
}           

複制

1.13.2 TreeSet

Tree樹形結構

Java第四周總結

TreeSet存儲方式

沒有比較方式無法存儲

Comparable接口使用

interface Comparable {

int compareTo(T t);

}

方法參數為T類型,由實作類遵從接口時限制,

compareTo方法,傳回值類型int類型,0, 負數,正數

0 表示兩個元素一緻,如果在TreeSet中比較結果為0,表示同一個元素,無法存儲第二個。

Comparable接口由存儲元素對應的類遵從,完成該方法

Comparator接口使用

interface Comparator {

int compare(T o1, T o2);

}

需要完成一個自定義比較器類對象,

int 傳回值 0,負數,正數

0 表示兩個元素一緻,如果在TreeSet中比較結果為0,表示同一個元素,無法存儲第二個。

Comparator使用要高于Comparable使用

2. Object類

2.1 Object類概述

Java中所有類的基類!!!

Java中所有的類都是間接或者直接繼承Object類。

Object類的引用資料類型變量可以儲存Java中任意資料類型空間的首位址。

Object類内規定了一些方法:

String toString();

目前對象建議String類型描述。預設情況是目前類所屬包名.類名@十六進制記憶體位址

如果對于資料類型展示有要求,可以重寫toString方法,在展示的方法中會預設執行toString方法

int hashCode();

記憶體中目前對象的唯一索引值,預設情況下是目前對象所處空間首位址的十進制展示。

boolean equals(Object obj);

比較方法,判斷兩個對象是否一緻,Object類内預設情況下比較的方式是位址比較。

兩個對象位址一緻,表示肯定是相同對象。如果我們期望修改equals比較規則,可以在目前類内重寫

【注意】

Java中規定,如果兩個對象的equals比較方法結果為true,要求hashCode值必須一緻。

下列方法之後再介紹:
線程有關方法
void wait();
void notify();
void notifyAll();

反射有關方法
Class<?> getClass();           

複制

2.2 toString方法:

食之無味,棄之可惜!!!

目前大家展示資料時,需要考慮使用的方法,可以通過Sout方法直接展示出對應的對象内

容。

使用DEBUG工具,一些輔助的可視化工具使用。

Eclipse Alt + Shift + S

2.3 equals方法

比較兩個對象是否一緻,在Object類内預設方式是比較兩個對象的位址是否一緻。

代碼中存在一些情況,需要比較的是兩個對象中儲存的内容是一直,但是使用Object類内繼承而來的equals方法,是不合理的!!!

【實作】

這裡需要重寫equals方法

代碼實作:

/*                                                                   
 * 重寫equals方法                                                        
 * 		1. 判斷兩個對象是不是同一個對象。如果調用方法的類對象和傳入參數類對象    
 * 		位址一緻,那就是同一個對象,傳回true,搞定!!!         
 *                                                                   
 * 		2. equals方法參數是Object類型,那也就是說任何類型的資料都可以作為參數。   
 * 		兩個資料類型不一緻,是否需要進行比較操作。                               
 * 		判斷資料類型是否一緻                                                   
 * 		使用關鍵字 instanceOf,同資料類型繼續運作,非同類型,結束判斷傳回false   
 * 		格式:                                                          
 * 			類對象 instanceOf 類名                                        
 *                                                                   
 * 		3. 判斷對象中儲存的資料                                                
 * 			Student中我們比較id, name, age, gender就可以了                    
 * 		                                                             
 */                                                                  
@Override                                                            
public boolean equals(Object obj) {                                  
	// 1. 判斷是不是同位址對象                                                 
	if (this == obj) {                                               
		return true;                                                 
	}                                                                
	                                                                 
	// 2. 類型是否一緻                                                     
	if (!(obj instanceof Student)) {                                 
		return false;                                                
	}                                                                
                                                            
	// 資料類型強制轉換                                                      
	Student stu = (Student) obj;                                     
	return this.id == stu.id                                         
			// this.name.equals(stu.name) 該equals方法是String類equals方法  
			&& this.name.equals(stu.name)                            
			&& this.age == stu.age                                   
			&& this.gender == stu.gender;                            
	                                                                 
}              

複制

2.4 hashCode方法

在Object類内,hashCode方法,傳回的内容是目前對象的空間首位址十進制展示方式。

目前類重寫equals方法之後,兩個目前類對象比較結果為true,那麼要求這兩個對象的hashCode必須一緻!!!

hashCode使用有一個唯一原則。

一般會參考參與equals比較的所有成員變量來組成對應的hashCode,這裡會使用到一些Java中提供的計算哈希值的方法。

hashCode使用未進行重寫的情況下,會使用位址作為hashCode對應的資料,重寫之後,不再使用位址。重寫之後hashCode 不對應目前對象所在位址。

代碼:

@Override
public int hashCode() {
	// 這裡通過Objects 工具類内的hash方法,傳入所有參與equals比較的成員變量
	// 得到對應的hashCode值
	return Objects.hash(id, name, age, gender);
}           

複制

3.1 什麼是Map

鍵(Key)值(Value)對

鄧超 = 娘娘

貝克漢姆 = 維多利亞

黃磊 = 孫莉

吳京 = 謝楠

表格:

姓名:張三

年齡:23

性别:男

程式開發大部分資料都是鍵值對形式的

MySQL JSON XML 類對象成員變量和存儲的資料

從前端發送的資料也可以轉成Map格式 ==> 一鍵生成 ==> 類對象 ==> 一鍵存儲 ==> 資料庫

interface Map<K, V>

–| class HashMap<K, V> 哈希表結構

–| class TreeMap<K, V> 底層是樹形結構,存儲要求K有對應的排序方式

Map雙邊隊列中鍵(Key)是唯一的,但是值(Value)可以重複

3.2 Map<K, V>雙邊隊列方法

增:

put(K k, V v);

存入一個鍵值對類型,K和V都要符合泛型限制

putAll(Map<? extends K, ? extends V> map);

存入另一個Map雙邊隊列,并且要求添加的Map雙邊對接中的K和V都要和目前Map中存儲

的K和V一緻

删:

remove(Object k);

删除對應K的鍵(Key)值(Value)對

改:

put(K k, V v);

對應目前K存在,修改對應内容

查:

int size();

目前Map雙邊隊列中,有效鍵值對個數

boolean isEmpty();

是否為空

boolean containsKey(Object key);

判斷指定的Key是否存在

boolean containsValue(Object value);

判斷指定Value是否存在

Set keySet();

傳回整個Map雙邊隊列中所有Key對應的Set集合

【注意】

一個方法使用set結尾,表示該方法傳回的是一個集合類型,大多是情況下都

是Set類型

Collection values();

傳回整個Map雙邊隊列中所有Value對應的Collection集合

【注意】

方法名如果是一個複數,傳回值類型集合或者是數組情況居多

3.3 EntrySet

Entry 可以認為是鍵值對對象

定義在Map類内

class Entry<K, V> {

K k;

V v;

}

K,V是完全依賴于Map限制的,這裡可以Entry裡面儲存的是每一個鍵值對類對象

Map中提供了一個方法

Set<Entry<K, V>> entrySet

傳回值是鍵值對類對象Set集合

Set集合中存儲的是Entry類型

Entry類型是帶有泛型的

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

public class Demo2 {
	public static void main(String[] args) {
		HashMap<String, String> map = new HashMap<String, String>();
		
		map.put("吳京", "謝楠");
		map.put("鄧超", "娘娘");
		map.put("黃磊", "孫莉");
		map.put("王寶強", "XX");
		
		Set<Map.Entry<String, String>> entrySet = map.entrySet();
		
		System.out.println(entrySet);
	}
}           

複制

3.4 TreeMap<K, V> 以及Comparable和Comparator

K是需要有對應的比較方式,如果沒有比較方式,無法存入。

推薦使用Comparator接口

import java.util.Comparator;
import java.util.TreeMap;

public class Demo3 {
	public static void main(String[] args) {
		TreeMap<String,String> map = new TreeMap<String, String>();
		
		map.put("李四", "1");
		map.put("王五", "1");
		map.put("趙六", "1");
		map.put("張三", "1");
		
		System.out.println(map);
		
		TreeMap<Dog,String> map2 = new TreeMap<Dog, String>(new Comparator<Dog>() {

			@Override
			public int compare(Dog o1, Dog o2) {
				return o1.getAge() - o2.getAge();
			}
		});
		
		map2.put(new Dog("王可可", 1), "111"); 
		map2.put(new Dog("八公", 2), "111"); 
		map2.put(new Dog("豆豆", 3), "111"); 
		map2.put(new Dog("老黃", 4), "111"); 
		map2.put(new Dog("旺财", 5), "111"); 
		
		System.out.println(map2);
		
	}
}           

複制

4. File

4.1 什麼是File類

SUN公司提供給開發者操作檔案和檔案夾的一個類對象。

Java中萬物皆對象,計算機中萬物皆檔案

擷取File類有三種方式【Constructor 構造方法】

File(String pathName);

根據對應的檔案路徑建立擷取對應的File類對象,可以是檔案,可以是檔案夾。

File(String parent, String child);

根據對應的父目錄檔案夾路徑,以及子檔案名或者子檔案夾名,建立對應的File類對象

File(File parent, String child);

根據對應的父目錄檔案夾File類對象,以及子檔案名或者子檔案夾名,建立對應File類對象

路徑:

相對路徑

. 目前工作目錄

… 父目錄/上級目錄

正對于目前工作目錄和其他檔案或者檔案夾之間的最小路徑

絕對路徑

唯一的路徑。

Windows作業系統 C D E F… 每一個盤符都是一個根目錄開始

C:/Windows/System32

Linux UNIX macOS

存在一個 / 目錄檔案

/user/liuxiaolei/appliction

路徑有一個很重要的東西

路徑分隔符

Windows 分隔符 預設是\

Linux UNIX macOS 分隔符 預設是 /

Windows是支援Linux分隔符 / 沒有任何問題

根據目前系統來區分不同的分隔符 File.separatorChar

代碼示範:

import java.io.File;

/*
 * 建立File類對象
 */
public class Demo1 {
	public static void main(String[] args) {
		/*
		 * 1. 路徑分隔符 \\ or / or File.separator
		 * 2. 操作檔案必須帶有檔案的字尾名 1.txt 2.java ...
		 */
		File file = new File("C:\\aaa");
		File file1 = new File("C:" + File.separator + "aaa");
		File file2 = new File("C:/aaa", "1.txt");
		File file3 = new File(file, "bbb");
			
	}
}           

複制

4.2 建立檔案和檔案夾

boolean createNewFile();

通過File類對象調用,建立對應File類對象中儲存的路徑的普通檔案。

建立成功傳回true,建立失敗傳回false

傳回false的原因:

1. 路徑不合法。

2. 對應的檔案夾沒有寫入權限。 rwxr-xr-x

3. 對應目前的檔案已經存在。

boolean mkdir();

通過File類對象調用,建立對應File類對象中儲存路徑的檔案夾

建立成功傳回true,建立失敗傳回false

傳回false的原因

1. 路徑不合法。

2. 對應的檔案夾沒有寫入權限。

3. 對應目前的檔案夾已經存在。

boolean mkdirs();

通過File類對象建立其中儲存的檔案目錄的所有對應檔案夾,包括中間路徑

如果建立失敗,傳回false

boolean renameTo(File dest);

通過File類對象調用,轉為目标File類對象dest

檔案/檔案夾移動,重命名

4.3 删除檔案或者檔案夾

boolean delete();

通過File類對象調用,删除對應的檔案或者檔案夾

【要求】

1. 删除的檔案或者檔案夾都是直接抹掉資料,不是放入資源回收筒

2. 無法删除非空檔案夾,檔案夾中存在其他内容無法整體删除。

void deleteOnExit();

程式退出時删除對應的檔案或者檔案夾

用于删除程式運作過程中,留下的日志檔案,緩沖檔案,記錄檔…

4.4 檔案屬性判斷[有用]

boolean isFile();

判斷是否是一個普通檔案

boolean isDirctory();

判斷是否是一個檔案夾

boolean isAbsolute();

判斷是否使用了絕對路徑

boolean isHidden();

判斷是否是隐藏檔案

boolean exists();

判斷檔案是否存在

4.5 擷取檔案屬性

用處不大的方法

下面的方法和檔案是否存在沒有一分錢關系,都可以使用字元串操作直接得到我們想要的結果

String getPath();

擷取File類對象儲存的路徑

String getName();

擷取目前File類對象中儲存的檔案名或者檔案夾名

String getParent();

擷取目前File類對象對應檔案或者檔案夾的父目錄路徑

String getAbsolutePath();

擷取當File類對象對應檔案或者檔案夾的絕對路徑

有用方法:

long lastModified()

擷取檔案的最後一次修改時間,傳回值是一個時間戳類型。

從1970年01月01日 00:00:00到現在的秒數。計算機元年

long length();

擷取檔案的大小,占用硬碟空間位元組數。

如果操作的是檔案夾,傳回0L

4.6 清單方法

static File[] listRoots();

通過File類調用,有且針對于Windows作業系統有效,擷取目前電腦内所有根盤符對象,如果是Linux,UNIX,macOS是無效的。

File[] listFiles();

通過File類對象調用,擷取目前File類對象對應檔案夾下的所有子檔案或者子檔案夾的File類對象數組

String[] list();

通過File類對象調用,擷取目前File類對象對應檔案夾下的所有子檔案或者子檔案夾的String類型檔案名或者檔案夾名字數組

4.7 FilenameFilter檔案名過濾器

interface FilenameFilter

boolean accept(File dir, String name);

源碼展示

@FunctionalInterface
public interface FilenameFilter {
    /**
     * Tests if a specified file should be included in a file list.
     *
     * @param   dir    the directory in which the file was found.
     * @param   name   the name of the file.
     * @return  <code>true</code> if and only if the name should be
     * included in the file list; <code>false</code> otherwise.
     */
    boolean accept(File dir, String name);
}           

複制

代碼實作:

import java.io.File;
import java.io.FilenameFilter;

/*
 * FilenameFilter過濾器示範
 */
public class Demo8 {
	public static void main(String[] args) {
		File file = new File("C:\\aaa\\ddd");
		
		// 使用匿名内部類的匿名對象直接作為方法的參數
		File[] listFiles = file.listFiles(new FilenameFilter() {
			
			@Override
			public boolean accept(File dir, String name) {
				/*
				 * dir是目前操作的檔案夾類對象
				 * name是目前檔案夾下的子檔案或者子檔案夾名字
				 * 
				 * 擷取對應的java檔案
				 * 		1. 判斷是不是普通檔案
				 * 		2. 判斷目前檔案名是不是.java結尾
				 */

				return new File(dir, name).isFile()
						// endsWith字元串方法,判斷目前字元串是不是已指定要求結尾
						&& name.endsWith(".java");
			}
		});
		
		// Lambda表達式 JDK1.8新特征 
		File[] listFile = file.listFiles((dir, name) -> 
			new File(dir, name).isFile() 
			&& name.endsWith(".java")
		);
		
		for (File file2 : listFile) {
			
			System.out.println(file2.getName());
		}
		
	}
}           

複制

5.String類

5.1 比較方式要求

Java第四周總結

5.2 擷取方法

int length();

擷取字元串長度 “”

char charAt(int index);

擷取String字元串中指定下标位置的char類型字元,如果index超出有效範圍

StringIndexOutOfBoundsException

int indexOf(char ch);

int indexOf(String str);

int indexOf(char ch, int fromIndex);

int indexOf(String str, int fromIndex);

這些方法都是擷取指定元素所在的下标位置,元素可以是char類型字元,也可以是字元串。這裡找出的是指定元素在字元串中第一次出現的位置,當然可以通過一定的限制,從哪個位置開始找fromIndex

int lastIndexOf(char ch);

int lastIndexOf(String str);

int lastIndexOf(char ch, int fromIndex);

int lastIndexOf(String str, int fromIndex);

這些方法都是擷取指定元素所在的下标位置,元素可以是char類型字元,也可以是字元串。這裡找出的是指定元素在字元串中最後一次出現的位置,當然可以通過一定的限制,從哪個位置開始找fromIndex

tips: 最後兩個方法有坑!!!

5.3 判斷方法

boolean endsWith(String str);

判斷目前字元串是不是以指定字元串結尾

boolean isEmpty();

判斷字元串是否為空 ""空串 JDK1.6之後 null不能讀取,不能寫入,不能調用方法

boolean equals(Object obj);

繼承重寫Object類内的方法,完成字元串要求的比較方式

boolean equalsIgnoreCase(String str);

不區分大小寫比較

boolean contains(String str);

判斷指定字元串是否存在

5.4 轉換方法

String(char[] arr);

使用字元數組中内容建立一個字元串對象

String(char[] arr, int offset, int length);

String(char[] arr, int off, int len);

String(char[] arr, int off, int cou);

String(char[] arg0, int arg1, int arg2);

使用字元數組中内容建立一個字元串對象,offset是從char類型數組中指定下标位置開始擷取資料,擷取的資料長度是length

static String valueOf(char[] arr);

通過類名調用的靜态方法,實際執行的是String(char[] arr);

static String valueOf(char[] arr, int offset, int length);

通過類名調用的靜态方法,實際執行的是String(char[] arr, int offset, int length);

char[] toCharArray();

傳回目前字元串對應的字元數組

5.5 其他方法

String replace(char oldChar, char newChar)

替換,替換不會修改原始的字元串,會建立一個新字元串傳回,并且替換效果是所有的對應 的oldChar全部替換成newChar

String[] split(String regex)

按照指定的字元串切割目前字元串

[00:00:15]XXXXXXX

String substring(int beginIndex)

從指定位置開始,截取子字元串,到字元串末尾

String substring(int beginIndex, int endIndex)

從指定位置開始beginIndex,到endIndex結束,要頭不要尾

String toUpperCase() 轉大寫

字元串小寫轉大寫

String toLowerCase() 轉小寫

字元串大寫轉小寫

String trim() 去除空格

去除字元串兩邊的無用空格

5.6 字元串小問題

String str = "孜然肉片";
str += "麻辣香鍋";
str += "番茄雞蛋";
str += "洋芋牛肉";
str += "烤羊排";
str += "金湯肥牛";
str += "蒜蓉油麥菜";

System.out.println("這裡有幾個字元串");           

複制

這裡一共有幾個字元串?

答案:

這裡有14個字元串

使用雙引号包含的字元串都是字元串常量!!!常量的概念中要求不可以修改。

雙引号包含的字元串都是存在于記憶體的【資料區】

+ 在字元串常量操作時,使用原本的兩個字元串拼接之後完成的一個新的字元串常量。

這裡導緻的字元串備援問題,後期會使用StringBuffer StringBuilder來解決問題。

5.7 記錄一個字元串中出現的英文字母個數【思考題】

小寫a幾次,大寫A幾次…

Java第四周總結

6. IO流

6.1 什麼是IO流

I

input 輸入流

read 讀取資料

O

output 輸出流

write 寫入資料

一般情況下都是按照目前程式使用的記憶體為參照物來考慮資料的走向問題。

檔案操作為例

從記憶體中儲存資料到硬碟 output

從硬碟中讀取資料到記憶體 input0

檔案操作為例

1GB完整的檔案拷貝過程,要遠遠高于1GB散檔案的拷貝過程。

1. 打開檔案,關閉檔案消耗資源較少

2. 1GB散檔案就需要不斷的打開,關閉資源

操作時間的消耗和打開檔案,關閉檔案或者說打開硬碟,關閉硬碟有直接關系

IO流基類

InputStream

輸入流基類

read

OutputStream

輸出流基類

write

6.2 IO流分類

流向分類

 輸入輸出

檔案操作處理單元分類

 位元組流和字元流

FileInputStream

 檔案操作輸入位元組流

FileOutputStream

 檔案操作輸出位元組流

FileReader

 檔案操作輸入字元流

FileWriter

 檔案操作輸出字元流

6.3 檔案操作位元組流

6.3.1 檔案操作輸入位元組流
FileInputStream 檔案操作輸入位元組流

Constructor 構造方法
	FileInputStream(File file);
		這裡是根據提供的File類對象建立對應的檔案操作輸入位元組流。

	FileInputStream(String pathName);	
		這裡是根據提供的String類型檔案路徑,建立對應的檔案操作輸入位元組流。
	都會抛出異常:
		FileNotFoundException 檔案未找到異常。

Method 成員方法	
	int read();
		從檔案中讀取一個位元組資料傳回到方法外。
		雖然傳回值是一個int類型,但是在整個int類型當中存儲的資料是一個byte類型,有
		且隻有低8位資料有效
		
	int read(byte[] buf);
		讀取檔案的内容是存儲在byte類型數組中,傳回值是讀取到的位元組個數
		
	int read(byte[] buf, int offset, int count);
		讀取檔案的内容是存儲在byte類型數組中,要求從byte數組offset位置開始,到
		count長度結束,傳回值是讀取到的位元組個數
	
	以上三個方法如果讀取到檔案末尾,傳回值都是 -1 EOF End Of File
	而且以上方法都要異常抛出
		IOException IO異常           

複制

6.3.2 使用示範
import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    /*
     * 檔案操作輸入位元組流
     * 	1. 确認讀取哪一個檔案
     * 	2. 建立對應檔案的FileInputStream
     * 	3. 讀取資料
     * 	4. 關閉資源 【重點】
     */
    public class Demo1 {
    	public static void main(String[] args) {
    		long start = System.currentTimeMillis();
    		
    		readTest1();
    		
    		long end = System.currentTimeMillis();
    		System.out.println("Time : " + (end - start));
    	}
    
    	public static void readTest2() {
    		// 1. 确定操作檔案
    		File file = new File("C:\\aaa\\1.txt");
    
    		// 2. 位元組輸入流讀取檔案對象
    		FileInputStream fileInputStream = null;
    		
    		try {
    			// 3. 根據File類對象建立對應的位元組輸入流
    			fileInputStream = new FileInputStream(file);
    			
    			// 4. 準備一個8KB位元組緩沖數組
    			byte[] buf = new byte[1024 * 8];
    			int length = -1;
    			
    			// 5. 讀取資料
    			while ((length = fileInputStream.read(buf)) != -1) {
    				System.out.println(new String(buf, 0, length));
    			}
    			
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			// 在finally代碼塊中關閉資源
    			if (fileInputStream != null) {
    				try {
    					fileInputStream.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    
    	/*
    	 * low!!!
    	 */
    	public static void readTest1() {
    		// 1. 确定操作檔案
    		File file = new File("C:\\aaa\\1.txt");
    		
    		// 2. 位元組輸入流讀取檔案對象 
    		FileInputStream fileInputStream = null;
    	
    		try {
    			// 3. 根據File類對象建立對應的位元組輸入流
    			fileInputStream = new FileInputStream(file);
    			
    			// 4. 讀取檔案 
    			int content = -1;
    			
    			while ((content = fileInputStream.read()) != -1) {
    				System.out.println((char)content);
    			}
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			// 用于處理代碼中使用到資源,無法發生什麼樣的錯誤,finally中的代碼一定會執行
    			// 這裡發現fileInputStream不是null,證明已經打開了檔案資源,關閉資源,捕獲異常
    			if (fileInputStream != null) {
    				try {
    					fileInputStream.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    }           

複制

6.3.3 檔案讀取使用緩沖和非緩沖差距

記憶體的運作速度看做是火箭

硬碟就是一個自行車

以上代碼中,使用緩沖之後,從硬碟中一口氣讀取8KB資料存儲在記憶體中,供程式使用。

8KB固态硬碟,4KB對齊。固态硬碟中每一個扇區都是4KB。緩沖這裡是要求CPU讀取兩個4KB資料,對于CPU而言沒有太多壓力。

如果是一個位元組一個位元組讀取,CPU取出4KB資料,結果有4095無效。

6.3.4 檔案操作輸出位元組流

FileOutputStream 檔案操作輸出位元組流

Constructor 構造方法:

FileOutputStream(File file);

根據File類對象建立對應的檔案輸出位元組流對象

FileOutputStream(String pathName);

根據String類型檔案路徑建立對應的檔案輸出位元組流對象

以上兩個構造方法,建立的FileOutputStream是删除寫/清空寫操作,會将原檔案中的内容全部删除之後,寫入資料。

FileOutputStream(File file, boolean append);

根據File類對象建立對應的檔案輸出位元組流對象。建立對象時給予append參數為

true,表示追加寫。

FileOutputStream(String pathName, boolean append);

根據String類型檔案路徑建立對應的檔案輸出位元組流對象,建立對象時給予append參數為true,表示追加寫。

FileOutputStream構造方法是擁有建立檔案的内容,如果檔案存在,不建立,檔案不存在且路徑正确,建立對應檔案。否則抛出異常FileNotFoundException

Method 成員方法:

void write(int b);

寫入一個位元組資料到目前檔案中,參數是int類型,但是有且隻會操作對應的低八位資料

void write(byte[] buf);

寫入位元組數組中的内容到檔案中

void write(byte[] buf, int offset, int length);

寫入位元組數組中的内容到檔案中,從指定的offset開始,到指定長度length

以上方法會抛出異常:IOException

6.3.5 使用示範
import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /*
     * 檔案操作輸出位元組流
     * 		1. 确定檔案
     * 		2. 建立FileOutputStream
     * 		3. 寫入資料到檔案中
     * 		4. 關閉資源 
     */
    public class Demo2 {
    	public static void main(String[] args) {
    		writeTest2();
    	}
    
    	public static void writeTest2() {
    		// 1. 确定檔案
    		File file = new File("C:/aaa/中國加油.txt");
    		
    		// 2. 檔案操作位元組輸出流對象
    		FileOutputStream fileOutputStream = null;
    		
    		try {
    			// 3. 建立FileOutputStream 
    			fileOutputStream = new FileOutputStream(file);
    			
    			// 4. 準備byte類型數組
    			byte[] bytes = "武漢加油!中國加油!".getBytes();
    			byte[] arr = {65, 66, 67, 68, 69, 70, 71};
    			
    			fileOutputStream.write(bytes);
    			fileOutputStream.write(arr, 2, 3);
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			// 關閉資源
    			if (fileOutputStream != null) {
    				try {
    					fileOutputStream.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    
    	public static void wrietTest1() {
    		// 1. 确定檔案
    		File file = new File("C:/aaa/武漢加油.txt");
    		
    		// 2. 檔案操作位元組輸出流對象
    		FileOutputStream fileOutputStream = null;
    		try {
    			// 3. 建立FileOutputStream
    			fileOutputStream = new FileOutputStream(file, true);
    			
    			// 4. 寫入資料
    			fileOutputStream.write('D');
    			fileOutputStream.write('D');
    			fileOutputStream.write('D');
    			fileOutputStream.write('D');
    			fileOutputStream.write('D');
    			fileOutputStream.write('D');
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			// 關閉資源
    			if (fileOutputStream != null) {
    				try {
    					fileOutputStream.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    	} 
    }           

複制

6.4 檔案操作字元流

6.4.1 字元流特征

字元流 = 位元組流 + 解碼過程

位元組組合操作 ==> 對應目前環境編碼集的一個字元

如果字元找不到,該資料無效,需要被删除。

如果是字元内容操作,效率還可以!!!

如果是非字元操作,兇多吉少!!!

字元流操作檔案

個人建議,該檔案可以使用notepad 記事本打開無亂碼,可以使用字元流操作。

視訊檔案,圖檔檔案,特定格式的檔案,都無法使用字元操作。

6.4.2 檔案操作輸入字元流

FileReader 檔案操作輸入字元流

Constructor 構造方法

FileReader(File file)

根據File類對象建立對應的FileReader字元流輸入對象

FileReader(String pathName)

根據String類型檔案路徑建立對應的FileReader字元流輸入對象

如果檔案不存在,抛出異常FileNotFoundException

Method 成員方法

int read();

讀取檔案中的一個字元資料,通過傳回值傳回,傳回值類型是int類型,但是在int類型中有且隻有低16位資料有效

int read(char[] arr);

讀取檔案中的資料儲存到字元數組中,傳回值類型是讀取到的字元個數

int read(char[] arr, int off, int len);

讀取檔案中的資料儲存到字元數組中,要求從數組中下标offset開始,到len結束,傳回值類型是讀取到的字元個數

以上方法,如果讀取到檔案預設,傳回值為-1 EOF End Of File

如果讀取操作工作中,出現問題,抛出異常IOException

6.4.3 使用示範
import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    
    public class Demo4 {
    	public static void main(String[] args) {
    		long start = System.currentTimeMillis();
    		
    		readTest2();
    		
    		long end = System.currentTimeMillis();
    		System.out.println("Time : " + (end - start));
    	}
    
    	// 10
    	public static void readTest2() {
    		FileReader fileReader = null;
    		try {
    			fileReader = new FileReader(new File("C:/aaa/3.txt"));
    			
    			char[] buf = new char[1024 * 4];
    			int length = -1;
    			
    			while ((length = fileReader.read(buf)) != -1) {
    				System.out.println(new String(buf, 0, length));
    			}
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			if (fileReader != null) {
    				try {
    					fileReader.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    
    	// 300
    	public static void readTest1() {
    		FileReader fileReader = null;
    		try {
    			fileReader = new FileReader(new File("C:/aaa/3.txt"));
    			
    			int content = -1;
    			
    			while ((content = fileReader.read()) != -1) {
    				System.out.println((char) content);
    			}
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			if (fileReader != null) {
    				try {
    					fileReader.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    }           

複制

6.4.4 檔案操作字元輸出流
FileWriter檔案操作輸出字元流

Constructor 構造方法
	FileWriter(File file);
		根據File類對象建立對應檔案的檔案操作輸出字元流
	FileWriter(String pathName);
		根據String類型檔案路徑建立對應檔案的檔案操作輸出字元流
	FileWriter(File file, boolean append);
		根據File類對象建立對應檔案的檔案操作輸出字元流,并要求為追加寫
	FileWriter(String pathName, boolean append);
		根據String類型檔案路徑建立對應檔案的檔案操作輸出字元流,并要求為追加寫
	
	如果建立FileWrite對象時,這裡檔案不存在,路徑合法,這裡會建立對應的操作檔案。如果路徑不合法,抛出異常 FileNotFoundException 
	
Method 成員方法	
	void write(int ch);
		寫入一個char類型資料到檔案中
	void write(char[] arr);
		寫入一個char類型數組到檔案中
	void write(char[] arr, int offset, int length);	
		寫入一個char類型數組到檔案中,要求從offset下标位置開始讀取數組資料,長度為
		length
	void write(String str);
		寫入一個字元串到檔案中
	void write(String str, int offset, int lenght);
		寫入一個字元串到檔案中,要求從指定字元串offset下标位置開始,長度為length
	如果寫入資料操作過程中,發生問題,這裡會有一個IOException           

複制

6.4.4 使用示範
import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    
    /*
     * 檔案操作字元輸出流
     */
    public class Demo1 {
    	public static void main(String[] args) {
    		FileWriter fileWriter = null;
    		
    		try {
    			fileWriter = new FileWriter(new File("D:/aaa/5.txt"), true);
    			
    			char[] charArray = "現在美國全國缺少口罩2.7億".toCharArray();
    			
    			fileWriter.write(charArray);
    			fileWriter.write("南韓目前疫情情況不容樂觀");
    			fileWriter.write("\r\n");
    			fileWriter.write(charArray, 0, 5);
    			fileWriter.write("南韓目前疫情情況不容樂觀", 0, 5);
    			
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			if (fileWriter != null) {
    				try {
    					fileWriter.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    		
    	}
    
    	private static void writeTest1() {
    		FileWriter fileWriter = null;
    		try {
    			fileWriter = new FileWriter(new File("D:/aaa/4.txt"), true);
    			
    			fileWriter.write('武');
    			fileWriter.write('漢');
    			fileWriter.write('加');
    			fileWriter.write('油');
    			fileWriter.write(',');
    			fileWriter.write('中');
    			fileWriter.write('國');
    			fileWriter.write('加');
    			fileWriter.write('油');
    			fileWriter.write(',');
    			fileWriter.write('世');
    			fileWriter.write('界');
    			fileWriter.write('加');
    			fileWriter.write('油');
    			
    			
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			if (fileWriter != null) {
    				try {
    					fileWriter.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    }           

複制

6.4.5 字元流檔案拷貝
import java.io.File;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    /*
     * 使用檔案操作字元流量拷貝非文本檔案問題
     * 【要求】
     * 		禁止使用字元流操作非文本檔案,記事本打開亂碼檔案都不可以
     */
    public class Demo2 {
    	public static void main(String[] args) {
    		FileReader fileReader = null;
    		FileWriter fileWriter = null;
    		
    		
    		try {
    			fileReader = new FileReader(new File("D:/aaa/logo桌面.jpg"));
    			fileWriter = new FileWriter(new File("D:/aaa/temp.jpg"));
    			
    			char[] buf = new char[1024 * 4];
    			int length = -1;
    			
    			while ((length = fileReader.read(buf)) != -1) {
    				fileWriter.write(buf, 0, length);
    			}
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			if (fileWriter != null) {
    				try {
    					fileWriter.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    			
    			if (fileReader != null) {
    				try {
    					fileReader.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    }           

複制

7. 緩沖流

7.1 緩沖流有什麼作用

使用緩沖數組以後,整體的讀取,寫入效率提升很大!!!

降低了CPU通過記憶體通路硬碟的次數。提高效率,降低磁盤損耗。

位元組輸入緩沖

BufferedInputStream

位元組輸出緩沖

BufferedOutputStream

字元輸入緩沖

BufferedReader

字元輸出緩沖

BufferedWrite

【重點】

所有的緩沖流都沒有任何的讀取,寫入檔案能力,這裡都需要對應的輸入流和輸出流來提供對應的能力。

在建立緩沖流流對象時,需要傳入對應的輸入流對象和輸出流對象。

底層就是提供了一個預設大小的緩沖數組,用于提高效率

7.2 位元組緩沖流

輸入

BufferedInputStream(InputStream in);

這裡需要的對象是一個位元組輸入流基類對象。同時也可也傳入InputStream子類對象

輸出

BufferedOutputStream(OutputStream out);

這裡需要的對象是一個位元組輸出流基類對象。同時也可也傳入OutputStream子類對象

以上傳入的InputStream和OutputStream都是用于提供對應檔案的讀寫能力。

7.2.1 位元組輸入流緩沖效率問題
  1. 在BufferedInputStream底層中有一個預設容量為8KB的byte類型緩沖數組。
  2. fill方法是一個操作核心

    a. 從硬碟中讀取資料,讀取的資料容量和緩沖數組容量一緻。

    b. 所有的read方法,都是從緩沖數組中讀取資料

    c. 每一次讀取資料之前,都會檢查緩沖區内是否有資料,如果沒有,fill方法執行,填充資料。

  3. 利用緩沖,fill方法,可以極大的降低CPU通過記憶體通路硬碟的次數。同時程式操作的資料是在記憶體中進行互動的。
7.2.2 位元組輸出流緩沖效率問題
  1. 在BufferedOutputStream類對象,預設有一個8KB的byte類型緩沖數組
  2. 資料寫入檔案時并不是直接儲存到檔案中,而是儲存在記憶體8KB位元組緩沖數組中
  3. 如果8KB空間填滿,會直接flush緩沖區,資料儲存到硬碟中,同時清空整個緩沖區。
  4. 在BufferedOutputStream關閉時,首先會調用flush方法,儲存資料到檔案,清空緩沖區,并且歸還緩沖區占用記憶體,同時關閉緩沖流使用的位元組輸出流。
7.2.3 緩沖流拷貝和非緩沖拷貝時間效率差別
import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Demo3 {
    	public static void main(String[] args) {
    		long start = System.currentTimeMillis();
    
    		copy();
    		
    		long end = System.currentTimeMillis();
    		// 總耗時
    		System.out.println("Time:" + (end - start));
    	}
    	
    	// 1716 ms
    	public static void useBuffered() {
    		BufferedInputStream bis = null;
    		BufferedOutputStream bos = null;
    		
    		try {
    			bis = new BufferedInputStream(new FileInputStream(new File("D:/aaa/2.txt")));
    			bos = new BufferedOutputStream(new FileOutputStream(new File("D:/aaa/buffered.txt")));
    			
    			int content = -1;
    			
    			while ((content = bis.read()) != -1) {
    				bos.write(content);
    			}
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			if (bos != null) {
    				try {
    					bos.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    			
    			if (bis != null) {
    				try {
    					bis.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
     	}
    	
        // 531000
    	public static void copy() {
    		FileInputStream fis = null;
    		FileOutputStream fos = null;
    		
    		try {
    			fis = new FileInputStream("D:/aaa/2.txt");
    			fos = new FileOutputStream("D:/aaa/copy.txt");
    			
    			int content = -1;
    			
    			while ((content = fis.read()) != -1) {
    				fos.write(content);
    			}
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			if (fos != null) {
    				try {
    					fos.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    			
    			if (fis != null) {
    				try {
    					fis.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    }           

複制

7.3 字元緩沖流

7.3.1 方法

BufferedReader

字元緩沖輸入流

BufferedReader(Reader reader);

BufferedWriter

字元緩沖輸出流

BufferedWriter(Writer writer);

7.3.2 字元緩沖流效率問題
  1. 字元緩沖輸入流,底層有一個8192個元素的緩沖字元數組,而且使用fill方法從硬碟中讀取資料填充緩沖數組
  2. 字元緩沖輸出流,底層有一個8192個元素的緩沖字元數組,使用flush方法将緩沖數組中的内容寫入到硬碟當中。
  3. 使用緩沖數組之後,程式在運作的大部分時間内都是記憶體和記憶體直接的資料互動過程。記憶體直接的操作效率是比較高的。并且降低了CPU通過記憶體操作硬碟的次數
  4. 關閉字元緩沖流,都會首先釋放對應的緩沖數組空間,并且關閉建立對應的字元輸入流和字元輸出流。
  5. 字元緩沖輸入流中

    String readLine(); 讀取一行資料

    字元緩沖輸出流中

    void newLine(); 換行

8. 序列化

8.1 序列化概述

Java中提供了一種序列化操作的方式,用一個位元組序列化來表示一個對象,該位元組序列化中儲存了【對象的屬性】,【對象的類型】和【對象的資料】。把位元組序列化儲存到檔案中,就可以做到持久化儲存資料内容。

從檔案中讀取位元組序列化資料,可以直接得到對應的對象。

8.2 ObjectOutputStream類

将對象資料序列化,儲存到檔案中

構造方法 Constructor
	ObjectOutputStream(OutputStream out);
		輸出位元組流對象作為目前方法的參數           

複制

import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    
    public class Demo1 {
    	public static void main(String[] args) {
    		
    		ObjectOutputStream objectOutputStream = null;
    		
    		try {
    			objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:/aaa/person.txt"));
    			
    			// 序列化對象,并且寫入到檔案中
    			objectOutputStream.writeObject(new Person(1, "騷磊", 16));
    			
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			if (objectOutputStream != null) {
    				try {
    					objectOutputStream.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    }           

複制

8.3 ObjectInputStream類

從檔案中讀取被序列化之後的位元組資料,提供反序列化操作,得到一個對象。

構造方法 Constructor
	ObjectInputStream(InputStream in);
	需要提供一個位元組輸入流對象來進行操作           

複制

【序列化注意事項】

  1. 如果一個類需要進行序列化操作,必須遵從。java.io.Serializable。不遵從無法進行序列化操作
  2. 序列化之後從檔案中讀取序列化内容,轉換成對應的對象,

    ClassNotFoundException 對應類沒有找到。

    對應的類型沒有導包,不存在…

    InvalidClassException 類型不一樣

    序列化之後的每一個類都會有一個serialVersionUID,該編号在使用過程中,序列化

    和反序列化必須一緻

  3. transient 修飾的成員變量不能被序列化

9.Java常用API

9.1. StringBuffer

9.1.1 StringBuffer概述

為了解決String字元串操作導緻的記憶體備援,提高效率,Java中提供了StringBuffer和StringBuilder來操作字元串,并且提供了很多方法,便于程式員開發。

StringBuffer和StringBuilder中都有char類型可變長數組作為字元串的儲存空間。使用到的方法類型和ArrayList類似。

StringBuffer 線程安全,效率較低

StringBuilder 線程不安全,效率較高

9.1.2 StringBuffer構造方法

構造方法 Constructor

StringBuffer();

建立一個未存儲任何字元串資訊的空StringBuffer空間,底層初始化一個16個字元char類型數組

StringBuffer(String str);

根據提供的String類型字元串建立對應的StringBuffer空間,底層char類型數組的容量會根據str.length + 16決定,并且儲存對應的str

9.1.3 添加方法

append(Everything)

在StringBuffer和StringBuilder對象中,添加另外的資料,并且當做字元串處理。

insert(int index, Everything)

在StringBuffer和StringBuilder對象中,在指定的下标位置,添加其他内容,并且當做

字元串處理

9.1.4 檢視方法

String toString();

将底層的char類型數組儲存的字元内容轉換成對應的String類型字元串傳回

int length();

傳回底層char類型數組中有多少有效元素。

String substring(int begin);

從指定位置開始擷取到char類型數組有效元素末尾對應的字元串,截取操作,

String substring(int begin, int end);

從指定位置begin開始到end結束,擷取對應的字元串,要頭不要尾

int indexOf(String str);

指定元素字元串所在下标位置

int lastIndexOf(String str);

指定元素字元串最後一次所在下标位置

9.1.5 修改方法

replace(int start, int end, String str);

從指定位置start開始,到end結束,start <= n < end, 使用str替換

setCharAt(int index, char ch);

使用ch替換指定下标index對應的字元

9.1.6 删除和反序

delete(int start, int end);

删除指定範圍以内的字元 start <= n < end

deleteCharAt(int index);

删除指定下标的字元

reverse();

逆序

9.2. Math數學類

Java中一些數學方法

public static double abs(double a);

傳回值為絕對值

public static double ceil(double a);

向上取整

public static double floor(double a);

向下取整

public static double round(double a);

四舍五入

public static double random();

随機數 0.0 <= n < 1.0

9.2.1 方法使用
package com.qfedu.b_math;

/*
 * Math工具類方法
 */
public class Demo1 {
	public static void main(String[] args) {
		// 絕對值
		System.out.println(Math.abs(1.5));
		System.out.println(Math.abs(-1.5));
		System.out.println(Math.abs(5));
		System.out.println(Math.abs(-5));
	
		System.out.println("--------------------------------");
		
		// 向上取整
		System.out.println(Math.ceil(1.5));
		System.out.println(Math.ceil(1.1));
		System.out.println(Math.ceil(-1.9));
		System.out.println(Math.ceil(-2.9));
		
		System.out.println("--------------------------------");
		
		// 向下取整
		System.out.println(Math.floor(10.5));
		System.out.println(Math.floor(10.1));
		System.out.println(Math.floor(-10.5));
		System.out.println(Math.floor(-10.1));
		
		System.out.println("--------------------------------");
		
		// 四舍五入
		System.out.println(Math.round(3.5)); // 4
		System.out.println(Math.round(3.4)); // 3
		System.out.println(Math.round(-2.5)); // -2
		System.out.println(Math.round(-2.4)); // -2
		System.out.println(Math.round(-2.6)); // -3
	}
}           

複制

9.2.2 抽獎小示範
package com.qfedu.b_math;

public class Demo2 {
	public static void main(String[] args) {
		for (int i = 0; i < 20; i++) {
			double num = Math.random() * 100;
			
			if (0.0 <= num && num < 50) {
				System.out.println("綠色普通卡");
			} else if (50 <= num && num < 80) {
				System.out.println("藍色高端卡");
			} else if (80 <= num && num < 98) {
				System.out.println("紫色傳說卡");
			} else {
				System.err.println("黃金史詩卡");
			}	
		}
	}
}           

複制

9.3. 月曆時間格式

9.3.1 Date 時期類[逐漸淘汰]

擷取目前系統時間

大部分構造方法已經過時

構造方法

Date();

建立一個Date,對應目前時間,精度在毫秒值

Date(long date);

根據時間戳毫秒數,建立對應的Date對象,時間戳是從1970-01-01 00:00:00 GMT

tips:

中國采用的東八區時間

1970-01-01 08:00:00

常用方法:

long getTime();

通過Date類對象擷取對應目前時間的毫秒數

System.currentTimeMillis(); 可以擷取目前系統時間戳毫秒數

9.3.2. DateFormat 日期格式類

DateFormat 是一個abstract修飾的類,用于轉換時間格式。

DateFormat不能直接使用,一般使用DateFormat子類SimpleDataFormat來使用

SimpleDataFormat構造方法中需要的參數是一個String,String類型的參數有特定的要求

辨別字母(區分大小寫) 對應含義
y
M
d
H 時(24小時)
m
s

String format(Date date);

根據指定比對要求,轉換Date格式成為字元串

Date parse(String format);

按照指定的比對規則,解析對應的字元串,傳回一個Date資料

9.3.3 Calender月曆類

Calender月曆類,替換了很多Date類中的方法。把很多資料都作為靜态的屬性,通過一些特定的方法來擷取。比Date處理日期資料更加友善。

Calender是一個abstract修飾的類,沒有自己的類對象。這裡通過特定的方法getInstance擷取Calender月曆類對象。

public static Calender getInstance();

預設目前系統時區的Calender對象

常用方法:

public int get(int field);

傳回特定資料的數值

public void set(int field, int value);

設定特定字段對應的資料

public Date getTime();

傳回得到一個Date對象,從計算機元年到現在的毫秒數,儲存在date對象中

字段名 含義
YEAR
MONTH 月(從0開始,使用時需要+1)
DAY_OF_MONTH 目前月的第幾天
HOUR 小時(12小時制)
HOUR_OF_DAY 小時(24小時制)
MINUTE 分鐘
SECOND
DAY_OF_WEEK 周幾(周日為1)

9.4. System類

System類提供了大量的靜态方法,操作的内容和系統有關。

可以擷取目前時間戳 long currentTimeMillis()

擷取系統屬性的方法 Properties getProperties();

退出目前程式 exit(int status)

數組拷貝方法 arrayCopy(Object src( 原數組), int srcPos(從原數組指定下标開始), Object dest(目标數組) , int destPos(目标數組從指定位置開始),int length( 讀取資料的個數) )

9.5. Runtime類

Runtime目前程式運作環境類對象,隻要程式啟動就會有對應的Runtime存在。

擷取Runtime對象的方法:

Runtime Runtime.getRuntime();

傳回值是Runtime

需要了解的方法:

gc(); JVM的GC機制,但是就算你調用了GC方法,也不會立即執行。

long totalMemory(); 目前程式使用的總記憶體

long freeMemory(); 目前程式使用的剩餘内容

long maxMemory(); Java程式能過申請的最大記憶體

Process exec(String exePath); 開啟一個程式

9.6. 包裝類

Java中提供了兩種資料類型

基本資料類型

byte short int long double float boolean char

引用資料類型

類對象,數組,字元串

Java中萬物皆對象,Java中提供了包裝類,讓基本類型也可以當做類對象來處理。

包裝之後的基本資料類型依然可以進行基本的操作和運算,但是多了一些特有的方法,增加了操作性。

問題:

ArrayList中如果儲存的資料類型是Integer類型

ArrayList元素:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

如果調用

remove(1); 删除的是誰???

基本類型 對應的包裝類(java.lang)
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character
9.6.1 自動裝箱和自動拆箱

基本類和包裝類型之間進行轉換的操作,這個過程就是"裝箱"和"拆箱"。

裝箱 從基本類型到包裝類

拆箱 從包裝類到基本類型

【不推薦】使用強制操作,太麻煩!!!

9.6.2 包裝類和字元串資料轉換過程

從文本中讀取的資料很多都是字元串類型,例如 JSON XML Database

除了Character字元包裝類之外,其他的包裝類都有對應的解析方法

以下方法都是static修飾的靜态方法

public static byte parseByte(String str);

public static short parseShort(String str);

public static int parseInt(String str);

public static long parseLong(String str);

public static float parseFloat(String str);

public static double parseDouble(String str);

public static boolean parseBoolean(String str);

以上方法都是對應的包裝類調用,解析成對應的基本資料類型。