|
Framework 集合框架是一個(gè)統(tǒng)一的架構(gòu),用來(lái)表示和操作集合. 集合框架主要是由接口,抽象類(lèi)和實(shí)現(xiàn)類(lèi)構(gòu)成. 接口:藍(lán)色;實(shí)現(xiàn)類(lèi):紅色 Collection |_____Set(HashSet) | |_____SortedSet(TreeSet) |_____List(LinkedList,ArrayList)
Collection:集合層次中的根接口,JDK沒(méi)有提供這個(gè)接口的實(shí)現(xiàn)類(lèi)。 Set:不能包含重復(fù)的元素,子接口SortedSet是一個(gè)按照升序排列的元素的Set。 List:可以包含重復(fù)的元素,是一個(gè)有序的集合,提供了按索引訪(fǎng)問(wèn)的方式,有次序,位置不改變。
Collection接口常用的方法:
boolean |
add(E
o) 確保此 collection
包含指定的元素(可選操作)。 |
boolean |
remove(Object
o) 從此 collection
中移除指定元素的單個(gè)實(shí)例,如果存在的話(huà)(可選操作)。 |
int |
size() 返回此 collection
中的元素?cái)?shù)。 |
List接口特有方法:
E |
get(int index)
返回列表中指定位置的元素。 |
SortedSet接口特有方法:
E |
first()
返回此有序集合中當(dāng)前第一個(gè)(最小的)元素。 |
E |
last()
返回此有序集合中最后一個(gè)(最大的)元素。 |
集合框架中的實(shí)現(xiàn)類(lèi).
ArrayList:
本質(zhì):我們可以將其看作是能夠自動(dòng)增長(zhǎng)容量的數(shù)組,實(shí)際是采用對(duì)象數(shù)組實(shí)現(xiàn)的。 自動(dòng)增長(zhǎng)容量就是當(dāng)數(shù)組不夠的時(shí)候,再定義更大的數(shù)組,然后將數(shù)組元素拷貝到新的數(shù)組. 例子:import
java.util.*; class ArrayListTest { public static void main(String[]
args) { ArrayList a1=new ArrayList(); a1.add("winsun");
a1.add("weixin"); a1.add("mybole");
for(int
i=0;i<a1.size();i++) {
System.out.println(a1.get(i)); } System.out.println(a1);
} }
結(jié)果:
winsun weixin mybole [winsun, weixin,
mybole]
利用ArrayList的toArray()返回一個(gè)對(duì)象的數(shù)組也可以利用Arrays.asList()方法返回一個(gè)列表
返回固定尺寸的列表,當(dāng)返回以后就不能修改列表的大小了,可以修改列表中元素的值,但不能增加容量,可以用set()方法對(duì)值進(jìn)行修改: Object
set(int index,Object
element) 用element替換指定的index的對(duì)象 Arrays.asList()和Collection.toArray()是作為數(shù)組和集合類(lèi)的一個(gè)橋 如果想從集合類(lèi)中獲得一個(gè)數(shù)組可以使用toArray()方法;如果想從數(shù)組中獲得一個(gè)列表可以使用asList()方法
:
import java.util.*; class Point { int x,
y; Point(int x, int y) { this.x = x; this.y = y; } public
String toString() { return "x=" + x + ",y=" + y; } } public class
ArrayListToArrayTest { public static void main(String[] args) {
ArrayList a1 = new ArrayList(); a1.add(new Point(3, 3)); a1.add(new
Point(4, 4)); a1.add(new Point(5, 5));
for (int i = 0; i < a1.size(); i++) {
System.out.println(a1.get(i)); }
System.out.println(a1);
Object[] objs = a1.toArray(); //
利用ArrayList的toArray()返回一個(gè)對(duì)象的數(shù)組. for (int i = 0; i < objs.length; i++)
{ System.out.println(objs[i]); }
System.out.println(objs);// List l = Arrays.asList(objs);//
Arrays.asList()返回一個(gè)列表. System.out.println(l);
} } 結(jié)果:
x=3,y=3 x=4,y=4 x=5,y=5 [x=3,y=3, x=4,y=4,
x=5,y=5] x=3,y=3 x=4,y=4 x=5,y=5 [Ljava.lang.Object;@1fc4bec [x=3,y=3,
x=4,y=4, x=5,y=5]
LinkedList類(lèi) LinkedList是采用雙向循環(huán)鏈表實(shí)現(xiàn)的. 利用LinkedList實(shí)現(xiàn)棧(stack),隊(duì)列(queue),雙向隊(duì)列(double-ended
queue)
LinkedList常用方法 void addFirst(Object o) void
addLast(Object o) Object getFirst() Object getLast() Object remove(int
index) boolean remove(Object o) Object removeFirst() Object
removeLast() 判斷是否為空 LinkedList繼承了一個(gè)方法isEmpty() 如果沒(méi)有包含任何元素返回true,沒(méi)有包含任何元素返回false ArrayList底層采用數(shù)組完成,而LinkedList則是以一般的 雙向鏈表完成,其內(nèi)每個(gè)對(duì)象除了數(shù)據(jù)本身外,還有兩個(gè)引用, 分別指向前一個(gè)元素和后一個(gè)元素. 如果我們經(jīng)常在List的開(kāi)始處增加元素,或者在List中進(jìn)行插入 和刪除操作,我們應(yīng)該使用LinkedList,否則的話(huà),使用ArrayList 將更加快速. 因?yàn)椴迦牒蛣h除都要移動(dòng)數(shù)組中的元素. 只是訪(fǎng)問(wèn)就用ArrayList,提供了按索引訪(fǎng)問(wèn)的機(jī)制.
HashSet HashSet實(shí)現(xiàn)了Set接口的hash
table(哈希表),依靠HashMap來(lái)實(shí)現(xiàn). 應(yīng)該為要存放到散列表的各個(gè)對(duì)象定義hashCode()和equals(). 因?yàn)閷?shí)現(xiàn)了set接口所以不能有重復(fù)的元素. 散列表: 散列表又稱(chēng)為哈希表. 散列表算法的基本思想: 以結(jié)點(diǎn)的關(guān)鍵字為自變量,通過(guò)一定的函數(shù)關(guān)系(散列函數(shù)) 計(jì)算出對(duì)應(yīng)的函數(shù)值,以這個(gè)值作為該結(jié)點(diǎn)存儲(chǔ)在散列表中的地址. 當(dāng)散列表中的元素存放太滿(mǎn),就必須進(jìn)行再散列,將產(chǎn)生一個(gè)新的散列表, 所有元素存放到新的散列表中,原先的散列表將被刪除. 在java語(yǔ)言中,通過(guò)負(fù)載因子(load
factor)來(lái)決定何時(shí)對(duì)散列表進(jìn)行再 散列.例如:如果負(fù)載因子是0.75,當(dāng)散列表中已經(jīng)有75%的位置已經(jīng)放滿(mǎn), 那么將進(jìn)行散列. 負(fù)載因子越高(越接近1.0),內(nèi)存的使用率越高,元素的尋找時(shí)間越長(zhǎng). 負(fù)載因子越低(越接近0.0),元素的尋找時(shí)間越短,內(nèi)存浪費(fèi)越多. HashSet類(lèi)的缺省負(fù)載因子是0.75.
HashSet在java.util包當(dāng)中. 需要導(dǎo)入. 常用方法 boolean
add(Object o) 需要使用迭代器 HashSet類(lèi)實(shí)現(xiàn)了Set接口,所以不能有重復(fù)的元素.
要根據(jù)散列碼計(jì)算存儲(chǔ)位置. 而散列碼是利用Object類(lèi)當(dāng)中的HashCode()函數(shù)獲得的. 而HashCode()函數(shù)是通過(guò)一個(gè)對(duì)象的內(nèi)存地址來(lái)得到散列碼的. 所以要重寫(xiě)public
int HashCode()方法. String類(lèi)實(shí)繼承了HashCode()方法. import java.util.*; public
class HashSetTest {
public static void main(String []args) {
HashSet hs=new HashSet(); /* hs.add("one"); hs.add("two");
hs.add("three"); hs.add("one"); */ hs.add(new
Student(1,"zhangsan")); hs.add(new Student(2,"lisi"));
hs.add(new Student(1,"zhangsan")); hs.add(new
Student(3,"wangwu")); Iterator it=hs.iterator();
while(it.hasNext()) { System.out.println(it.next());
} } } class Student { int num; String name; Student(int
num,String name) { this.name=name; this.num=num; } public
int HashCode() { return num*name.hashCode(); } public boolean
equals(Object o) { Student s=(Student)o; return num==s.num
&& name.equals(s.name); } public String toString() {
return "name :
="+name; } } 需要覆蓋HashCode()和equals()方法 HashSet->HashCode->對(duì)象內(nèi)存地址
TreeSet: TreeSet是依靠TreeMap來(lái)實(shí)現(xiàn)的. TreeSet是一個(gè)有序集合,TreeSet中元素將按照升序排列, 缺省是按照自然排序進(jìn)行排列,意味著TreeSet中元素要 實(shí)現(xiàn)Comparable接口. 我們可以在構(gòu)造TreeSet對(duì)象時(shí),傳遞實(shí)現(xiàn)了Comparator接口 的比較器對(duì)象. java.util包當(dāng)中TreeSet類(lèi) import
java.util.*; public class TreeSetTest
{ //如果自定義類(lèi)對(duì)象要加入TreeSet要實(shí)現(xiàn)Comparable接口 public static void main(String
[]args) { TreeSet ts=new TreeSet(new
Student.StudentComparator()); /* ts.add("winsun");
ts.add("weixin"); ts.add("mybole"); */ ts.add(new
Student(2,"lisi")); ts.add(new Student(1,"wangwu")); ts.add(new
Student(3,"zhangsan")); ts.add(new Student(3,"mybole"));
Iterator it=ts.iterator(); while(it.hasNext()) {
System.out.println(it.next()); } } } class Student implements
Comparable { int num; String name; static class StudentComparator
implements Comparator { public int compare(Object o1,Object o2)
{ Student s1=(Student)o1; Student s2=(Student)o2; int
result=s1.num>s2.num ? 1 : (s1.num==s2.num ? 0 : -1);
if(result==0) { //String類(lèi)實(shí)現(xiàn)了compareTo()方法.
result=s1.name.compareTo(s2.name); } return result;
} } public static void printElements(Collection c) { Iterator
it=c.iterator(); while(it.hasNext()) {
System.out.println(it.next()); } } Student(int num,String
name) { this.name=name; this.num=num; } public int
HashCode() { return num*name.hashCode(); } public boolean
equals(Object o) { Student s=(Student)o; return num==s.num
&& name.equals(s.name); } public int compareTo(Object
o) { Student s=(Student)o; return
num>s.num?1:(num==s.num?0:-1); } public String toString() {
return
num+":"+name; } } ** HashSet是基于Hash算法實(shí)現(xiàn)的,其性能通常優(yōu)于TreeSet. 通常都應(yīng)該使用HashSet,在需要排序的功能時(shí),才使用 TreeSet. **
迭代器:
Collection提供了一個(gè)iterator()方法,可以返回一個(gè)迭代器,迭代器是指向兩個(gè)元素之間的指針。凡是繼承自Collection的接口或間接的實(shí)現(xiàn)類(lèi)都有這個(gè)方法. 其中有3個(gè)方法 1.hasNext() 2.next()
3.remove()
hasNext()判斷是否有更多的元素,如果有返回true remove()方法remove()方法需要?jiǎng)h除上一個(gè)返回的元素,需要先調(diào)用next()方法后在用remove(),返回的列表有時(shí)不一定真正實(shí)現(xiàn)remove()方法,根據(jù)需要決定是否實(shí)現(xiàn). 如:ArrayList
al1=new ArrayList(); Iterator
it=al.iterator(); it.next(); while(it.hasNext()) { System.out.println(it.next()); } 通用方式訪(fǎng)問(wèn)集合中的元素 另外定義打印函數(shù) public
static void printElements(Collection c) { Iterator
it=c.iterator(); while(it.hasNext()) {
System.out.println(it.next()); } }
Map(HashMap) |_____SortedMap(TreeMap)
Map:存儲(chǔ)的是key-value對(duì),不能包含重復(fù)的key,可以有重復(fù)的value。子接口SortedMap是一個(gè)按升序排列key的Map。 在系統(tǒng)區(qū)windows目錄下有win.ini 有鍵和對(duì)應(yīng)的值 asf=MPEGVideo 注冊(cè)表存儲(chǔ)的也是這種類(lèi)型. 就是用Map接口所提供的方法來(lái)存儲(chǔ). SortedMap是一個(gè)按照升序排列key的Map.
Map接口實(shí)現(xiàn)類(lèi):
HashMap:
對(duì)key進(jìn)行散列. keySet()..values()..entrySet().. HashMap是實(shí)現(xiàn)了Map接口的Hash表. 實(shí)現(xiàn)了所有hashmap操作,允許空值和空鍵. HashSet底層就是hashmap的實(shí)現(xiàn). map接口沒(méi)有add()方法. 要放置元素通過(guò)put()方法. Object
put(Object key,Object value) 獲取元素的時(shí)候 Object get(Object
key) 通過(guò)鍵獲取值 Hash表,通過(guò)鍵計(jì)算出相對(duì)應(yīng)的存儲(chǔ)位置的值,并輸出.
常用的方法 Set keySet() 返回一個(gè)鍵的視圖類(lèi)型是Set. Collection
values() 返回一個(gè)值的視圖類(lèi)型是Collection. Set
entrySet() 返回一個(gè)鍵值對(duì)視圖類(lèi)型是Set. 返回的Set集合當(dāng)中每一個(gè)對(duì)象都是一個(gè)Map.Entry對(duì)象. Map.Entry是一個(gè)靜態(tài)的接口. 接口中提供了常用方法 Object
getKey() Object getValue() ***************************** import
java.util.*; public class HashMapTest {
public static void printElements(Collection
c) { Iterator it=c.iterator(); while(it.hasNext()) {
System.out.println(it.next()); } } public static void main(String
[]args) { HashMap hm=new HashMap(); hm.put("1", "zhang3");
hm.put("2", "li4"); hm.put("3", "wang5");
System.out.println(hm.get("1")); System.out.println(hm.get("2"));
System.out.println(hm.get("3")); Set keys=hm.keySet();
System.out.println("-----------keys---------");
printElements(keys);
Collection values=hm.values();
System.out.println("-----------values---------");
printElements(values); Set entrySets =hm.entrySet();
System.out.println("------------entrySets-----------");
printElements(entrySets); Iterator it=entrySets.iterator();
while(it.hasNext()) { Map.Entry me=(Map.Entry)it.next();
System.out.println(me.getKey()+" = "+me.getValue());
} } }
** TreeMap是實(shí)現(xiàn)了sorted
Map接口的類(lèi) TreeMap按照key進(jìn)行排序. 類(lèi)似HashMap用法 ********************** HashMap和TreeMap比較 和Set類(lèi)似,HashMap的速度通常都比TreeMap快, 只有在需要排序的功能的時(shí)候,才使用TreeMap.
另外有用的類(lèi) Collections類(lèi)不同于Collection類(lèi) Collections.sort()主要是對(duì)列表排序. 1.自然排尋natural
ordering 2.實(shí)現(xiàn)比較器Comparator接口 取最大元素Collections.max(). 取最小元素Collections.min(). 在已經(jīng)排序的List中搜索指定的元素. Collections.binarySearch(). static
void sort(List
list)方法是按升序?qū)χ付斜砼判? 自然排序法. 列表中元素必須都實(shí)現(xiàn)了comparable接口.與Arrays.sort()是一樣的. comparable接口在java.lang包當(dāng)中. 實(shí)現(xiàn)comparable接口就要實(shí)現(xiàn)compareTo()方法. compareTo()大于返回正數(shù),等于返回0,小于返回負(fù)數(shù).
class Student implements Comparable { int
num; String name; Student(int num,String name) {
this.num=num; this.name=name; } public int compareTo(Object
o) { Student s=(Student)o; return
num>s.num?1:(num==s.num?0:-1); } public String toString() {
return num+":"+name; } }
public static void printElements(Collection
c) { Iterator it=c.iterator(); while(it.hasNext()) {
System.out.println(it.next()); } } public static void main(String
[]args) { Student s1=new Student(2,"zhangsan"); Student s2=new
Student(1,"lisi"); Student s3=new Student(3,"wangwu"); ArrayList a1=new
ArryList(); a1.add(s1); a2.add(s2); a3.add(s3); Collections.sort(a1); printElements(a1); } 排序的時(shí)候可以傳遞一個(gè)比較器. Comparator接口. java.util包當(dāng)中. 有兩個(gè)方法int
compare(Object o1,Object
o2) 兩個(gè)對(duì)象進(jìn)行比較當(dāng)對(duì)象1大于對(duì)象2的時(shí)候返回1, 當(dāng)對(duì)象1等于對(duì)象2的時(shí)候返回一個(gè)0, 當(dāng)對(duì)象1小于對(duì)象2的時(shí)候返回一個(gè)負(fù)數(shù). 和boolean
equals(Object
obj)方法. 實(shí)現(xiàn)一個(gè)比較器. 比較器總是和一個(gè)特定的類(lèi)相關(guān). 為某一個(gè)類(lèi)指定一個(gè)比較器. 利用內(nèi)部類(lèi)實(shí)現(xiàn)比較器接口. **內(nèi)部類(lèi) 聲明為靜態(tài)方法就不需要產(chǎn)生外部類(lèi)對(duì)象. class
Student implements Comparable { int num; String name; Student(int
num,String name) { this.num=num; this.name=name; } public
int compareTo(Object o) { Student s=(Student)o; return
num>s.num?1:(num==s.num?0:-1); } public String toString() {
return num+":"+name; } static class StudentComparator implements
Comparator { public int compare(Object o1,Object o2) {
Student s1=(Student)o1; Student s2=(Student)o2; int
result=s1.num>s2.num ? 1 : (s1.num==s2.num ? 0 : -1);
if(result==0) { //String類(lèi)實(shí)現(xiàn)了compareTo()方法.
result=s1.name.compareTo(s2.name); } return result;
} } }
public static void printElements(Collection
c) { Iterator it=c.iterator(); while(it.hasNext()) {
System.out.println(it.next()); } } public static void main(String
[]args) { Student s1=new Student(2,"zhangsan"); Student s2=new
Student(1,"lisi"); Student s3=new Student(3,"wangwu");
ArrayList
a1=new
ArryList(); a1.add(s1); a2.add(s2); a3.add(s3); Collections.sort(a1,Student.StudentComparator()); printElements(a1); } Collections類(lèi)中提供了一種反序排列方式. 本身返回就是一個(gè)比較器對(duì)象 static
Comparator reverseOrder()
Arrays.sort()也可以指定一個(gè)比較器對(duì)象 static void sort(Object[]
a,Comparator c) Collections類(lèi)主要對(duì)列表操作. Arrays類(lèi)主要對(duì)數(shù)組操作.
Vector集合類(lèi) Vector:用ArrayList代替Vector. Vector內(nèi)所有方法都是同步的,存取元素效率低. 在多線(xiàn)程中可以使用 在Collection類(lèi)中提供了 static
list synchronizedList(List
list) 可以返回一個(gè)同步列表 可以將列表實(shí)參傳遞進(jìn)去會(huì)返回一個(gè)安全的線(xiàn)程同步列表 還有 static Collection
synchronizedCollection(Collection c) static Set synchronizedSet(Set
s)
Hashtable:用HashMap代替Hashtable 需要同步Map的時(shí)候 可以用Collection類(lèi)的方法 static
Map synchronizedMap(Map
m) 但是還是Hashtable獲取的同步Map快一些.
Stack集合類(lèi):
Stack:用LinkedList代替Stack. Stack是從java.util.Vector繼承而來(lái). 還從Vector繼承了alementAt()方法. 同時(shí)Stack還繼承了不需要的特性. 所以要使用棧的時(shí)候要用LinkedList來(lái)自己實(shí)現(xiàn).
Properties屬性類(lèi).是從Hashtable繼承而來(lái)也是存儲(chǔ)鍵值對(duì)的. 表示一個(gè)持久的屬性集合. 可以存儲(chǔ)win.ini的鍵值對(duì). 在 java.lang.System類(lèi)當(dāng)中 有 static
Properties getProperties() 檢測(cè)當(dāng)前系統(tǒng)的屬性 可以使用 void list(PrintStream
out)打印系統(tǒng)屬性 還可以讀取一個(gè)配置文件: 先建立一個(gè)配置文件 winsun.ini 寫(xiě)入 company=winsun author=sunxin corpyright=2003-2004 先實(shí)例化一個(gè)Property對(duì)象 在用 void
load(InputStream
inStream)方法 可以從一個(gè)輸入流中加載一個(gè)屬性列表. 輸入流可以用java.io包中的一個(gè)類(lèi)構(gòu)造. 可用 Enumeration
propertyNames() 返回Enumeration對(duì)象.返回所有鍵的枚舉. Enumeration是一個(gè)接口 提供了兩個(gè)方法 boolean
hasMoreElements() Object nextElement() 需要返回值的時(shí)候 String
getProperty(String key) 返回鍵對(duì)應(yīng)的值 import java.util.*; import
java.io.FileInputStream; import java.io.*; public class ProTest
{ public static void main(String []args) { /* Properties
pps=System.getProperties(); pps.list(System.out); */
Properties pps=new Properties(); try { pps.load(new
FileInputStream("d:/workspace/ProTest/bin/winsun.ini")); Enumeration
ENUM=pps.propertyNames(); while(ENUM.hasMoreElements()) {
String str=(String)ENUM.nextElement(); String
strValue=pps.getProperty(str); System.out.println(str+" =
"+strValue); }
} catch(FileNotFoundException e)
{ e.printStackTrace(); } catch(IOException ex) {
ex.printStackTrace(); } }
}
static String getProperty(String key) static String
getProperty(String key,String def)
|