關於一些基礎的Java問題的解答(九)

上一篇文章的傳送門:關於一些基礎的Java問題的解答(八)


41.Collections工具類的shuffle方法

Java中Collections類的shuffle()方法的作用是將List中的內容隨機打亂順序

其源碼如下:

public static void shuffle(List<?> list) {  
    if (r == null) {  
        r = new Random();  
    }  
    shuffle(list, r);  
}  
private static Random r;  
 
 
public static void shuffle(List<?> list, Random rnd) {  
    int size = list.size();  
    if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {  
        for (int i=size; i>1; i--)  
            swap(list, i-1, rnd.nextInt(i));  
    } else {  
        Object arr[] = list.toArray();  
 
        // Shuffle array  
        for (int i=size; i>1; i--)  
            swap(arr, i-1, rnd.nextInt(i));  
  
        // Dump array back into list  
        ListIterator it = list.listIterator();  
        for (int i=0; i<arr.length; i++) {  
            it.next();  
            it.set(arr[i]);  
        }  
    }  
}

shuffle方法使用了Random類,通過把list其中的元素隨機交換size次,打亂list元素的順序

42.Java 找不到或無法加載主類

如果在你沒有打錯類名的前提下,可能是Java解釋器搜索的目錄沒有包含當前目錄,一般而言Java解釋器會搜索環境變量下的ClassPath目錄
因此我們可以爲我們的ClassPath環境變量添加:.;
也可以調用java解釋器的時候帶上參數:-cp .

43.Java中單件模式的實現方法

在Java中,單件模式的實現方法有以下五種:懶漢、餓漢、靜態內部類、枚舉以及雙重校驗鎖

懶漢的實現方法如下(只有在使用的時候才進行初始化):

public class SingleInstance {
	
	public static SingleInstance instance = null;
	
	public static synchronized SingleInstance getInstance() {
		if (instance == null) {
			instance = new SingleInstance();
		}
		return instance;
	}
	
	private SingleInstance() {}
	
}

餓漢的實現方法如下(提前進行初始化):

public class SingleInstance {
	
	public static SingleInstance instance = new SingleInstance();
	
	public static SingleInstance getInstance() {
		return instance;
	}
	
	private SingleInstance() {}
	
}

靜態內部類的實現方法如下(只有在初次使用時纔會加載內部靜態類,實例化單件實例):

public class SingleInstance {
	
	public static SingleInstance getInstance() {
		return InnerStaticClass.instance;
	}
	
	private SingleInstance() {}
	
	private static class InnerStaticClass {
		private static SingleInstance instance = new SingleInstance();
	}
}

枚舉的實現方法如下:

public enum SingleInstance {
	
	INSTANCE;

	private SingleInstance() {}
	
}


雙重校驗鎖實現方法:

public class SingleInstance {
	
	public static SingleInstance instance;
	
	public static SingleInstance getInstance() {
		if (instance == null) {
			synchronized (SingleInstance.class) {
				if (instance == null) {
					instance = new SingleInstance();
				}
			}
		}
		return instance;
	}
	
	private SingleInstance() {}
	
}

44.如何判斷兩個float是否相等

首先兩個float是不能直接使用==來判斷是否相等的,一般而言,我們有兩種寫法:

較嚴格的:

Math.abs(a-b) <= 0
較寬鬆的:

Math.abs(a-b) <= 0.00000001

45.Java對象序列化

在Java中,序列化對象是一種把對象轉換爲字節碼的方法,我們可以通過ObjectOutputStream以及ObjectInputStream來實現對象的序列化以及反序列化

當我們需要把某個對象進行序列化時,我們需要爲對象implement Serializable接口來“標記”可以序列化該對象
序列化以及反序列化能爲我們保存對象的成員變量,當我們不希望某個成員變量被序列化時,我們可以使用transient關鍵字來標記它

反序列化時,系統通過 static final long serialVersionUID 來判斷字節碼與class是否一致,如果不一致則會拋出異常

一般而言,serialVersionUID如果沒有顯示聲明,系統會根據class的成員變量爲其設置一個值(這將會導致class成員變量修改時我們的反序列化出現異常,不過我們可以通過自行顯示設置 serialVersionUID來解決這個問題)

一般而言,系統會自行處理對象序列化以及反序列化的過程,不過我們也可以通過實現以下方法來對該過程進行控制(系統序列化之前會通過反射判斷是否有對應方法,如果有則把流程交給其處理):
 private void writeObject(java.io.ObjectOutputStream out) throws IOException
 private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
 private void readObjectNoData() throws ObjectStreamException;




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章