java進階(三):反射(3)——陣列的反射與集合的運用(ArrayList、HashSet)
一、陣列的反射
1、簡單的陣列反射:
1)同樣型別切且具有相同維度的陣列擁有同一份位元組碼
2)getName()和getSuperclass()方法/* * 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
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)——陣列的反射與集合的運用(ArrayList、HashSet)
一、陣列的反射 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框架:事務管理、Spring與Hibernate整合)
一、事務控制 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 進階面試問題列表,程式設計師“三金四銀”面試季必知!(拒絕傻瓜式分享)
開發十年,就只剩下這套架構體系了! >>>
Java中使用new Date()和System.currentTimeMillis()獲取當前時間戳的區別(轉)(Java進階-性能提升)
使用 get csdn 比較 his new mem ava 輸出 在開發過程中,通常很多人都習慣使用new Date()來獲取當前時間,使用起來也比較方便,同時還可以獲取與當前時間有關的各方面信息,例如獲取小時,分鐘等等,而且還可以格式化輸出,包含的信息是比較豐富的。但是
Java進階(三)Java安全通訊:HTTPS與SSL
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!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” />