1. 程式人生 > >java進階(三):反射(3)——陣列的反射與集合的運用(ArrayList、HashSet)

java進階(三):反射(3)——陣列的反射與集合的運用(ArrayList、HashSet)

一、陣列的反射

1、簡單的陣列反射:

1)同樣型別切且具有相同維度的陣列擁有同一份位元組碼

	/*
		 * 5- 陣列的的反射
		 */
		int[] a1 = new int[3]; 
		int[] a2 = new int[4]; 
		int[][] a3 = new int[2][3]; 		
		String[] a4 = new String[3];
		
		System.out.println(a1 == a2);//false
		
		//同樣型別切且具有相同維度的陣列擁有同一份位元組碼
		System.out.println(a1.getClass() == a2.getClass());//true
2)getName()和getSuperclass()方法
		
		System.out.println(a1.getClass().getName());//[I : [-表示陣列,I-整數,具體見文件
		System.out.println(a4.getClass().getName());//[Ljava.lang.String;
		
		//得到父類getSuperclass(),顯示其父類的名字
		System.out.println(a1.getClass().getSuperclass().getName());//java.lang.Object
		System.out.println(a4.getClass().getSuperclass().getName());//java.lang.Object

2、Arrays和Array類的使用。

1)java.util.Arrays類:對陣列操作的類,封裝了大量靜態方法運算元組。

例如:A、給陣列賦值:通過fill方法;

   B、對陣列排序:通過sort方法,按升序;

   C、比較陣列:通過equals方法比較陣列中元素值是否相等;

   D、查詢陣列元素:通過binarySearch方法能對排序好的陣列進行二分查詢法操作。

		int[] b1 = {9,6,3};
		String[] b2 = {"Z","Y","A"};
		String [] c = new String[3];
		
		//列印陣列
		System.out.println(Arrays.asList(b1));//看不到值,原因是int不屬於Object [[
[email protected]
] System.out.println(Arrays.asList(b2));//可以看到列印的值 [Z, Y, A] //給陣列賦值 Arrays.fill(c, "4"); System.out.println("檢視資料C--"+Arrays.asList(c));//檢視資料C--[4, 4, 4] //對陣列排序:通過sort方法,按升序 Arrays.sort(b2); System.out.println("排序後的陣列b2--"+Arrays.asList(b2));//排序後的陣列b2--[A, Y, Z]

2)java.lang.reflect.Array類:可以得到反射陣列的型別,對反射陣列進行賦值等操作。

        int[] temp={1,2,3,4,5};
        Class<?>demo = temp.getClass().getComponentType();
        System.out.println("陣列型別: "+demo.getName());
        System.out.println("陣列長度  "+Array.getLength(temp));
        System.out.println("陣列的第一個元素: "+Array.get(temp, 0));
        Array.set(temp, 0, 100);
        System.out.println("修改之後陣列第一個元素為: "+Array.get(temp, 0));
【輸出】

陣列型別: int
陣列長度  5
陣列的第一個元素: 1
修改之後陣列第一個元素為: 1


3、綜合運用:

/**
	 * 方法:傳一個object,打印出來,陣列就遍歷
	 * @param obj
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	private  static void printObject(Object obj) throws InstantiationException, IllegalAccessException{
		Class clazz = obj.getClass();
		if(clazz.isArray()) {//判斷陣列
			
			int len = Array.getLength(obj);//得到陣列的長度
			for (int i = 0; i < len; i++) {
				System.out.print(Array.get(obj, i));
			}
			System.out.println();
			for(int i = 0; i < len; i++){
				Array.set(obj, i, 99);//賦值
				System.out.print(Array.get(obj, i));

			}
		}else {
			System.out.println();
			System.out.println(obj);
			
		}
	}
	
}
        int[] temp={1,2,3,4,5};		
        printObject(temp);//呼叫
        printObject("khjkhj");//呼叫
【輸出】

12345
9999999999
khjkhj

二、ArrayList_HashSet的比較及Hashcode分析。

1、先定義一個實體,暫時沒有重寫父類的equals()和hashCode()方法。

package com.onhance.reflection;

/**
 * 
 * @title 反射用到的例項
 * @description
 * @author SAM-SHO
 * 
 * @Date 2014-6-29
 */
public class ReflectPoint {



	private int x;
	public int y;
	
	public String str1 = "ball";
	public String str2 = "basketball";
	public String str3 = "SAM SHO";
	
	
	public ReflectPoint(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
	
	

	@Override
	public String toString() {
		return "ReflectPoint [str1=" + str1 + ", str2=" + str2 + ", str3="
				+ str3 + "]";
	}


}

2、分別定義四個ReflectPoint物件,然後增加equals()hashCode()方法

		//1-先定義物件
		ReflectPoint pt1 = new ReflectPoint(3, 3);
		ReflectPoint pt2 = new ReflectPoint(5, 5);
		ReflectPoint pt3 = new ReflectPoint(7, 7);		
		ReflectPoint pt4 = new ReflectPoint(7, 7);
		
		//1-2比較pt3和pt4的關係
		//在ReflectPoint類重寫hashcode與equals方法前為 : false,重寫後,為true;
		System.out.println(pt3.equals(pt4));
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + x;//x、y參與雜湊演算法
		result = prime * result + y;
		return result;
	}



	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ReflectPoint other = (ReflectPoint) obj;
		if (x != other.x)
			return false;
		if (y != other.y)
			return false;
		return true;
	}

清楚的看到:pt3和pt4比較在前後發生的變化。

3、把例項分別放入ArrayList和HashSet容器,觀察容器的大小。

//2-1 ArrayList集合
		//不管ReflectPoint有沒有重寫hashcode與equals方法,不管pt1-pt4之間的關係,長度適中為5
		//因為ArrayList有順序,可以重複
		Collection <Object> list = new ArrayList<Object>();
		list.add(pt1);
		list.add(pt2);
		list.add(pt3);
		list.add(pt4);
		list.add(pt1);
		System.out.println("ArrayList的長度 : "+list.size());//顯示長度為5
		
		//2-2 HashSet集合
		// 首先pt1只能放一個。
		// 沒有重寫hashcode和equesl方法時,pt3和pt4不 equals,即指向的不是同一個物件。所以都能放進去,長度為4
		// 重寫hashcode和equesl方法後,pt3和pt4指向同一個物件,放不進去,長度為3.
		// 因為HashSet沒有有順序,不可以重複
		Collection <Object> set = new HashSet<Object>();
		set.add(pt1);
		set.add(pt2);
		set.add(pt3);
		set.add(pt4);   //pt3 equals pt4 重複,沒有重寫hashcode和equesl方法,就可以放進去)
		set.add(pt1);  //重複,放不進去,只能放一個pt1
		System.out.println("HashSet的長度 : "+set.size());//3個、4個

4、這邊對雜湊演算法作簡單介紹:

1)、雜湊演算法提高從集合中查詢元素的效率,將集合分成若干個區域每個物件可以計算出一個雜湊碼,可以將雜湊碼分組,每組分別對應某個儲存區域,根據一個物件的雜湊碼就可以確定該物件應該儲存在哪個區域。

2)、HashSet底層用的也是陣列。當向陣列中利用add(Object o)新增物件的時候,系統先找物件的hashCode。
int hc=o.hashCode(); 返回的hashCode為整數值:Int I=hc%n;(n為陣列的長度),取得餘數後,利用餘數向陣列中相應的位置新增資料,以n為6為例,如果I=0則放在陣列a[0]位置,如果I=1,則放在陣列a[1]位置。如果equals()返回的值為true,則說明資料重複。如果equals()返回的值為false,則再找其他的位置進行比較。這樣的機制就導致兩個相同的物件有可能重複地新增到陣列中,因為他們的hashCode不同。如果我們能夠使兩個相同的物件具有相同hashcode,才能在equals()返回為真。

5、當一個物件被存進集合中,不要去修改這個物件參加hash演算法的屬性,不然會破壞雜湊演算法。導致存進去的物件與修改後的物件具有不同的雜湊值。這樣最直接的問題就是,集合中的那個物件無法刪除(當然有其他辦法處理),造成記憶體洩露。

在上例中,x/y參與了雜湊演算法,現在改變y的值,看一下結果:

		//可以取走,結果長度為2
		set.remove(pt1);//可以取走
		System.out.println("HashSet的長度 : "+set.size());//2個
		
		//不可取走,結果為3
		pt1.y = 99;//y用於hashcode方法的計算,修改值以後,取不走:會導致記憶體洩露
		set.remove(pt1);//取不走
		System.out.println("HashSet的長度 : "+set.size());//3個
		
		set.clear();//我們可以清除
		System.out.println("HashSet的長度 : "+set.size());//0個

備註(寫給自己):以後我會繼續整理java中集合的內容。包括資料結構的內容和thinking in java中的內容。

相關推薦

java反射3——陣列反射集合運用ArrayListHashSet

一、陣列的反射 1、簡單的陣列反射: 1)同樣型別切且具有相同維度的陣列擁有同一份位元組碼 /* * 5- 陣列的的反射 */ int[] a1 = new int[3]; int[] a2 = new int[4]; int[][] a3 =

DDD實戰第一波(五)開發一般業務的大健康行業直銷系統實現產品上下文領域層

討論 clas 基本 ted ctc decimal nco protect pan 從這篇文章開始,我們根據前面的DDD理論與DDD框架的約束,正式進入直銷系統案例的開發。 本篇文章主要講產品上下文中的領域層的主要實現,先簡單講下業務方面的需求:產品SPU與產品SKU,產

Java併發程式設計8多執行緒環境中安全使用集合API含程式碼

Java併發程式設計(8):多執行緒環境中安全使用集合API(含程式碼)JAVA大資料中高階架構 2018-11-09 14:44:47在集合API中,最初設計的Vector和Hashtable是多執行緒安全的。例如:對於Vector來說,用來新增和刪除元素的方法是同步的。如果只有一個執行緒與Vector的例

Java並發編程8多線程環境中安全使用集合API含代碼

本質 extend xxxx args 控制 一段 連續 並發 xtend Java並發編程(8):多線程環境中安全使用集合API(含代碼)JAVA大數據中高級架構 2018-11-09 14:44:47在集合API中,最初設計的Vector和Hashtable是多線程安全

Java面試系列之一哥們,你們的系統架構中為什麼要引入訊息中介軟體?

歡迎關注個人公眾號:石杉的架構筆記(ID:shishan100) 週一至週五早8點半!精品技術文章準時送上! “ 這篇文章開始,我們把訊息中介軟體這塊高頻的面試問題來給大家說一下,也會涵蓋一些MQ中介軟體常見的技術問題。假如說面試官看你簡歷裡寫了MQ中介軟體的使用經驗,很可能會有如下的問題:你們公司生產

Java併發程式設計】之八多執行緒環境中安全使用集合API含程式碼

在集合API中,最初設計的Vector和Hashtable是多執行緒安全的。例如:對於Vector來說,用來新增和刪除元素的方法是同步的。如果只有一個執行緒與Vector的例項互動,那麼,要求獲取

Java學習第十四天泛型反射泛型註解Log4J日誌元件

一、泛型 1、概述 泛型是JDK1.5以後才有的,可以在編譯時期進行型別檢查,且可以避免頻繁型別轉化! // 執行時期異常 @Test public void testGeneric() throws Exception { // 集合的宣告 List list

Java學習第十天Lucene

一、Lucene概念 1、回顧索引 ① 定義:索引是對資料庫表中一列或多列的值進行排序的一種結構 ② 目的:加快對資料庫表中記錄的查詢 ③ 特點:以空間換取時間,提高查詢速度快 2、什麼是Lucene Lucene是apache軟體基金會發布的一個開放原始碼的全文檢索引擎工具包,

Java學習第二十三天Spring框架代理模式AOP程式設計jdbc支援

一、共性問題 1、伺服器啟動報錯,什麼原因? ① jar包缺少或者jar包衝突 ◆ 先檢查專案中是否缺少jar包引用 ◆ 伺服器:檢查jar包有沒有釋出到伺服器下;使用者庫jar包,需要手動釋出到tomcat(每次新建專案) ◆ 重新發布專案 ② 配置檔案錯誤(

Java學習第二十四天Spring框架事務管理SpringHibernate整合

一、事務控制 1、引入 使用者訪問 > Action > Service > Dao 如何保證: 在service中呼叫2次dao,其中一個dao執行失敗,整個操作要回滾 2、事務控制概述 ① 程式設計式事務控制:自己手動控制事務 Jdbc程式

java泛型

1、泛型簡介 所謂泛型,即通過引數化型別來實現在同一份程式碼上操作多種資料型別,泛型程式設計是一種程式設計正規化,他利用“引數化型別”將型別抽象化,從而實現更為靈活的複用。 先簡單給個例子: //可以想象這裡的T為Integer型別,以便於理解,其實它可以是任何型別 p

Java學習第十四天WebService

一、WebService介紹 1、使用場景 ① 不同的移動客戶端訪問 ② 需要訪問第三方的專案 2、ISO的七層模型:物理層、資料鏈路層、網路層、傳輸層、表示層、會話層、應用層 3、基於Socket建立Web服務 ① Socket通訊的服務端,實現大小寫轉化 publ

Java學習第十三天MyBatis

一、MyBatis基礎 1、回顧jdbc開發 ① 優點:簡單易學、上手快、非常靈活構建SQL、效率高 ② 缺點:程式碼繁瑣,難以寫出高質量的程式碼(例如:資源的釋放,SQL注入安全性等)開發者既要寫業務邏輯,又要寫物件的建立和銷燬,必須管底層具體資料庫的語法(例如:分頁)。 ③ 適合

Java學習第十二天SpringMVC

一、回顧struts2+Spring開發 1、需求:學生註冊【add.jsp > StudentAction.java > addOK.jsp】 ① Emp.java public class Emp { private String id;//編號 privat

Java學習第十一天EasyUI

一、省-市-區三級聯動【struts2 +非資料庫版】 public class Bean { private String province;//省份 private String city;//城市 public Bean(){} public String getPro

Java中使用new Date()和System.currentTimeMillis()獲取當前時間戳的區別Java-性能提升

使用 get csdn 比較 his new mem ava 輸出 在開發過程中,通常很多人都習慣使用new Date()來獲取當前時間,使用起來也比較方便,同時還可以獲取與當前時間有關的各方面信息,例如獲取小時,分鐘等等,而且還可以格式化輸出,包含的信息是比較豐富的。但是

Java()Java安全通訊HTTPSSSL

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Java學習第十五天Struts框架

一、自定義一個Struts框架 1、MVC模式包括 Model:模型 View:檢視 Control:控制器 2、傳統mvc開發總結 ① 跳轉程式碼寫死,不靈活 ② 每次都去寫servlet,要web.xml中配置servlet! 3、自定義一個Struts框架 ① 配置檔案

Java學習第十三天檔案上傳下載JavaMail郵件開發

一、檔案上傳與下載 1、檔案上傳 案例:登錄檔單/儲存商品等相關模組! 頭像 / 商品圖片(資料庫:儲存圖片路徑 / 圖片儲存到伺服器中指定的目錄) 2、檔案上傳要點 ① 表單提交方式:post ② 表單中有檔案上傳的表單項: <input type=”file” />