Java類集(二)

foreach及Enumeration接口

JDK1.5之後增加了許多新的功能,其中foreach可以輸出數組,實際上foreach語法中同樣也支持集合的輸出操作

import java.util.ArrayList;
import java.util.List;
public class ForeachDemo01 {
 public static void main(String[] args) {
  List<String> all=new ArrayList<String>();
  all.add("Hello");
  all.add("_");
  all.add("World");
  for (String str: all) {
   System.out.println(str+",");
  }
 }}

實際上Iterator屬於一個新的輸出接口,在最早Java剛出來的時候如果向要輸出,使用Enumeration接口完成輸出。但是在Java因爲存在發展的歷史問題,所以有些地方還會使用到Enumeration輸出。而且必須注意的是在使用Enumeation的時候一般是直接操作Vector類完成的。

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
public class ForeachDemo02 {
 public static void main(String[] args) {
  Vector<String> vector=new Vector<String>();
  vector.add("Hello");
  vector.add("_");
  vector.add("World");
  Enumeration<String> enumeration=vector.elements();
  while (enumeration.hasMoreElements()) {
   System.out.println(enumeration.nextElement()+",");
  }
 }}

在所有的輸出操作中,以Iterator接口爲標準的輸出操作,這一點始終記住。
在部分舊的操作中Enumeration依然存在。

Map接口

Map接口的常用子類:

  • HashMap
  • Hashtable
  • TreeMap
  • WeekHashMap

之前所學的Collection,Set,List接口都屬於單值操作,即每次只能操作一個對象,而Map與它們不同的是,每次操作的是一對對象,即二元偶對象,Map中的每個元素都使用Key->value的形式存儲在集合之中。接口定義如下:public interface Map<K,V>

Map.Entry接口

Map.Entry是Map中內部定義的一個接口,專門用來存放key->value的內容

Map.Entry接口定義:public static interface Map.Entry<K,V>;

Map.Entry接口的常用方法:

  • public loolean equals(Object o) 對象比較
  • public K getKey() 取得Key
  • public V getValue() 取得value
  • public int hashCode() 返回哈希碼
  • public V setValue(V value) 設置value的值
    Map與Map.Entry的關係
    在這裏插入圖片描述
    Map接口的常用子類:
  • HashMap:無序存放,是新的操作類,key不允許重複
  • Hashtable:無序存放,是舊的操作類,Key不允許重複
  • TreeMap:是可以排序的Map集合,按集合中的Key排序,但是Key不允許重複
  • WeakHashMap:弱引用的Map集合,當集合中的某些內容不再使用時,可以清除掉無用的數據,九二幺使用gc進行回收
  • IdentityHashMap:key可以重複的Map集合
    以HashMap爲例的基本操作方法:
import java.util.HashMap;
import java.util.Map;
public class HashMapDemo01 {
 public static void main(String[] args) {
  Map<String, String> map=null;//聲明Map對象,其中Key和value的類型爲String
  map=new HashMap<String, String>();
  map.put("學號1", "張三");//增加內容
  map.put("學號2", "李四");
  map.put("學號3", "王五");
  String val=map.get("學號1");//根據Key取出值
  System.out.println("取出的值爲"+val);
 }
}

在map中也可以使用containsXXX()方法判斷指定的key或者value是否存在

if(map.containsKey("學號1')){
System.out.println("搜索的Key存在!")}//判斷Key是否存在

else{System.out.println("搜索的Key不存在!")}

if(map.containsValue("學號1')){
System.out.println("搜索的Value存在!")}//判斷Value是否存在

else{System.out.println("搜索的Value不存在!")}

如果輸出所有的key,使用如下方法:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HashMapDemo03 {
 public static void main(String[] args) {
  Map<String, String> map=null;//聲明Map對象,其中Key和value的類型爲String
  map=new HashMap<String, String>();
  map.put("學號1", "張三");//增加內容
  map.put("學號2", "李四");
  map.put("學號3", "王五");
  Set<String> keys=map.keySet();//得到全部的key
  Iterator<String> iterator=keys.iterator();
  while(iterator.hasNext()){
   String str=iterator.next();
   System.out.print(str+",");
  }
 }
}

既然可以輸出所有的Key,那麼也可以輸出全部的value

Collecation <String> iter=map.values();//得到全部的value

在Map中也存在一個Hashtable子類,實際上這個子類的推出時間與Vector一樣,都屬於舊的類

Map<String,String> map=null;

map=new Hashtable<String,String>();

其他的步驟跟HashMap沒啥區別

HashMap Hashtable
性能 採用異步處理方式,性能更高 採用同步處理方式,性能較低
線程安全 屬於非線程安全的操作類 屬於線程安全的操作類

在Map中還存在一個TreeMap的子類,此類也屬於排序類,按key排序。

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapDemo01 {
 public static void main(String[] args) {
   Map<String, String> map=null;
   map=new TreeMap<String, String>();
   map.put("A","小明");
   map.put("B", "小李");
   map.put("C", "小王");
   Set<String> keysSet=map.keySet();//得到所有的key
   Iterator<String> iterator=keysSet.iterator();
   while (iterator.hasNext()) {
  String string=iterator.next();
  System.out.println(string+">>>>"+map.get(string));//取出內容
 }
 }
}

使用TreeMap可以方便的完成排序的操作,如果自定義的類想要作爲key的話,則肯定需要實現Comparable接口,指定比較規則。

如果假設一個Map中某些內容長時間不使用的話,按照之前的做法時不會刪除掉的,如果希望其可以自動刪除,可以說使用弱引用。當裏面的某些內容不使用時,可以自動刪除掉。

import java.util.Iterator;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.Set;
import java.util.TreeMap;
public class WeakHashMapDemo01 {
 public static void main(String[] args) {
   Map<String, String> map=null;
   map=new WeakHashMap<String, String>();
   map.put(new String("A"),new String("小王"));
   map.put(new String("B"),new String("小明"));
   map.put(new String("C"),new String("小李"));
   System.gc();//強制性進行垃圾的回收機制
   System.out.println(map);
   map.put(new String("D"),new String("小wang"));
   System.out.println(map);
 }
}
  • 強引用:當內存不足時,JVM寧願出現OutOfMemeryError錯誤而使程序停止,也不會回收此對象來釋放空間;

  • 軟引用:當內存不足時,會回收這些對象的內存,用來實現內存敏感的高速緩存;

  • 弱引用:無論內存是否緊張,被垃圾回收器發現,立即回收;

  • 虛引用:和沒有任何引用一樣

小總結:

  • 介紹了Map的特點及基本操作

  • Map和Map.Entry的關係

  • Map的子類:HashMap,Hashtable,TreeMap,WeakHashMap

  • 主要功能就是查找,根據Key查找到value

Map接口的使用注意事項

對於Map接口來說,其本身是不能迭代直接使用迭代(例如:Iterator,foreach)進行輸出,因爲Map中的每個位置存放的是一對值(key->value),而Iterator中每次只能找到一個值,所以如果此時非要進行迭代輸出的話,則必須按照以下的步驟完成:

1:將Map的實例通過entrySet()方法變爲Set接口對象;

2:通過Set接口實例爲Iterator實例化

3:通過Iterator迭代輸出,每個內容都是Map.Entry的對象

4:通過Map.Entry進行Key->value的分離

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class IteratorDemo4 {
 public static void main(String[] args) {
  Map<String, String> map=null;
  map=new HashMap<String, String>();
  map.put("學號1", "小明");
  map.put("學號2", "小李");
  map.put("學號3", "小王");
        Set<Map.Entry<String, String>> allSet=null;
        allSet=map.entrySet();//獲得Map.Entry<String, String>集合
        Iterator<Map.Entry<String, String>> iterator=null;//迭代器類型爲Map.Entry<String, String>
        iterator=allSet.iterator();
        while (iterator.hasNext()) {
   Map.Entry<String, String> meEntry=iterator.next();
   System.out.println(meEntry.getKey()+"---->"+meEntry.getValue());//Map.Entry<String, String>提供了getKey()和getValue()的方法
  }
 }
}

第一種方式是通過Ierator完成,當然,在JDK1.5之後也可以使用foreach完成。

forach(Map.Entry<String,String> me: map.entrySet()){
  System.out.println(meEntry.getKey()+"---->"+meEntry.getValue());//Map.Entry<String, String>
}

兩種輸出形式最終實際上還是以Collection的形式輸出,只是以Map.Entry作爲內容的操作類型
在Map中可以使用任意的類型作爲Key和value,那麼非系統類也可以。

import java.util.HashMap;
import java.util.Map;
class Person{
 private String name;
 private int age;
 public Person(String name,int age) {
  this.name=name;
  this.age=age;
 }
 public String toString(){
  return "姓名: "+this.name+";年齡: "+this.age;
 }
}
public class HashMapDemo05 {
 public static void main(String[] args) {
  Map<String, Person> map=null;
  map=new HashMap<String, Person>();
  map.put("zhangsan", new Person("張三", 30));
  System.out.println(map.get("zhangsan"));
 }
}

如果現在以String爲key是可以取出內容的,但如果以下:

map.put(new Person("張三", 30), "zhangsan");
 System.out.println(map.get(new Person("張三", 30)));

以自定的類作爲Key,但無法取值,則結果爲空!!!

實際上,對於匹配過程,對象要一樣才能進行匹配查找

Person per=new Person("張三", 30);
map.put(per, "zhangsan");
 System.out.println(map.get(per));

若上方能查找
但是這樣並不是解決問題的方法,因爲不可能將Person的對象per對象到處帶着走,應該像String一樣,可以使用匿名對象的形式找到內容

那麼此時,實際上就需要按照與Set接口中判斷重複元素的方式一樣,進行方法重寫:


 public boolean equals(Object object) {
  if (this==object) {
   return true;
  }
  if (!(object instanceof Person)) {
   return false;
  }
  Person person=(Person)object;
  if (this.name.equals(person.name)&&this.age==person.age){
   return true;
  }
  else {
   return false;
  }
 }
 public int hashCode(){
  return this.name.hashCode()*this.age;
 }

作爲Key,或者更確切的說作爲對象的時候,實際上是依靠hashCode()和equals()來判斷兩個匿名對象是否相等,這一點由系統內部自動完成。
總結:
Map可以使用迭代輸出

map->entrySet->Set->Iterator->Map.Entry->key和value

如果使用非系統類作爲key,則一點要在該類中重寫equals()和hashCode()方法,否則無效。

IdentityHashMap類:

使用HashMap操作的時候,key內容是不允許重複的。

 public static void main(String[] args) {
           Map<Person00, String> map=null;
           map=new HashMap<Person00, String>();//聲明Map對象
           map.put(new Person00("張三", 30), "zhangsan_1");
           map.put(new Person00("張三", 31), "zhangsan_2");
           map.put(new Person00("李四", 32), "lisi");
           Set<Map.Entry<Person00, String>> allSet=null;
           allSet=map.entrySet();
           Iterator<Map.Entry<Person00, String>> iterator=allSet.iterator();//接受Set的全部內容
           while (iterator.hasNext()) {
   Map.Entry<Person00, String> mEntry=iterator.next();
   System.out.println(mEntry.getKey()+"-->"+mEntry.getValue());
   
  }
 }

如果現在希望Key的內容可以重複,(兩個對象的地址不一樣)則要使用第二個子類

Map<Person00, String> map=null;
map=new IdentityHashMap<Person00, String>();//聲明Map對象

就算是兩個對象的內容相等,但是因爲都使用了new關鍵字,所有地址肯定不等,那麼就可以加進去,key是可以重複的

SortedMap類:

​​在這裏插入圖片描述

import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
public class SortedMapDemo {

 public static void main(String[] args) {
  SortedMap<String, String> map=null;
  map=new TreeMap<String, String>();
  map.put("D", "小明");
  map.put("B", "小李");
  map.put("C", "小王");
  map.put("A", "小六");
  System.out.println("第一個元素的內容的key:"+map.firstKey());
        System.out.println("對應的值:"+map.get(map.firstKey()));
     System.out.println("最後一個元素的內容"+map.lastKey());
     System.out.println(":對應的值:"+map.get(map.lastKey()));
     System.out.println("返回小於指定範圍的集合:");
     for (Map.Entry<String, String> meEntry:map.headMap("B").entrySet()) {
   System.out.println(meEntry.getKey()+"-->"+meEntry.getValue());
  }
     System.out.println("部分集合:");
     for (Map.Entry<String, String> meEntry:map.subMap("B","D").entrySet()) {
   System.out.println(meEntry.getKey()+"-->"+meEntry.getValue());
  }
 }
}

SortedMap類:
在這裏插入圖片描述

Collections類:

在面試題中可能會問這樣一個問題:請回答Collections和Collection的區別:

Collections和collection沒有直接的關係,但是與集合的各個接口都有操作的方法支持。

List<String> allList=Collections.emptyList();//返回空的List集合
  Set<String>allSet=Collections.emptySet();
  allList.add("Hello");

以上的輸出爲null,因爲Collections沒有提供add()方法

  • 增加:
    allList.addALL(allList,“A”,“B”,"…");

  • 內容反轉:

Collection.reverse(allList);

  • 檢索數據:

int point=Collections.binarySearch(allList,“A”);

  • 替換內容:

allList.addALL(allList,“A”,“W”);//第三個參數爲要替換的新的內容

。。。。。剩下的很多方法可查找API。

Stack類:

方法:

  • public push (item ) 把項 壓入棧頂。其作用與 addElement (item ) 相同。

參數 item 壓入棧頂的項 。 返回: item 參數 ;

  • public pop () 移除棧頂對象,並作爲函數的值 返回該對象。

返回:棧頂對象(Vector 對象的中的最後一項)。

拋出異常 : EmptyStackException 如果堆棧式空的 。。。

  • public peek() 查看棧頂對象而不移除它。。

返回:棧頂對象(Vector 對象的中的最後一項)。

拋出異常 : EmptyStackException 如果堆棧式空的 。。。

  • public boolean empty (測試堆棧是否爲空。) 當且僅當堆棧中不含任何項時 返回 true,否則 返回 false.

  • public int search (object o) 返回對象在堆棧中位置, 以 1 爲基數, 如果對象 o是棧中的一項,該方法返回距離 棧頂最近的出現位置到棧頂的距離; 棧中最上端項的距離

        Stack stack = new Stack(); // 創建堆棧對象
        System.out.println("11111, absdder, 29999.3 三個元素入棧");
        stack.push(new Integer(11111)); //向 棧中 壓入整數 11111
        printStack(stack);  //顯示棧中的所有元素
        stack.push("absdder"); //向 棧中 壓入
        printStack(stack);  //顯示棧中的所有元素
        stack.push(new Double(29999.3)); //向 棧中 壓入
        printStack(stack);  //顯示棧中的所有元素
        String s = new String("absdder");
        System.out.println("元素absdder在堆棧的位置"+stack.search(s));     
        System.out.println("元素11111在堆棧的位置"+stack.search(11111));
        System.out.println("11111, absdder, 29999.3 三個元素出棧"); //彈出 棧頂元素
        System.out.println("元素"+stack.pop()+"出棧");
        printStack(stack);  //顯示棧中的所有元素
        System.out.println("元素"+stack.pop()+"出棧");
        printStack(stack);  //顯示棧中的所有元素
        System.out.println("元素"+stack.pop()+"出棧");
        printStack(stack);  //顯示棧中的所有元素

Properties類集:

在類集屬性中提供了專門的Properties類以完成屬性的操作。

public class Properties extends Hashtable(Object,Object)

proties是Hashtable的子類,則也是Map的子類,可以使用Map的全部操作,但是一般情況下屬性類是單獨使用的。

設置屬性:public Object setProperty(String Key,String key)
得到屬性:
   public String getProperty(String key)
   public String getProperty(String key,String defaultValue)

以下爲設置和讀取屬性

import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;
public class PropertiesDemo {

 public static void main(String[] args) {
         Properties per=new Properties();//設置Properties對象
         per.setProperty("BJ", "beijing");//設置屬性
         per.setProperty("TJ", "tianjing");
         per.setProperty("SH", "shanghai");
System.out.println("BJ屬性存在:"+per.getProperty("BJ"));

System.out.println("SC屬性不存在:,同時設置顯示的默認值"+per.getProperty("SC","沒有發現"));
 }
}

以下將屬性保存到問價之中,提供了這個方法:public void store(OutputStream out,String comments)throws IOException

import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;
public class PropertiesDemo {

 public static void main(String[] args) {
         Properties per=new Properties();//設置Properties對象
         per.setProperty("BJ", "beijing");//設置屬性
         per.setProperty("TJ", "tianjing");
         per.setProperty("SH", "shanghai");
         File file=new File("D:"+File.separator+"area.properteis");//指定要操作的文件
         try {
   per.store(new FileOutputStream(file),"Area Info");//保存屬性到普通文件
  } catch (Exception e) {
   // TODO: handle exception
  }
 }
}

那麼也可以讀取文件:

import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
public class PropertiesDemo02 {

 public static void main(String[] args) {
         Properties per=new Properties();//設置Properties對象
         per.setProperty("BJ", "beijing");//設置屬性
         per.setProperty("TJ", "tianjing");
         per.setProperty("SH", "shanghai");
         File file=new File("D:"+File.separator+"area.properteis");//指定要操作的文件
         try {
   per.load(new FileInputStream(file));//讀取文件
  } catch (Exception e) {
   // TODO: handle exception
  }
         System.out.print("BJ屬性存在"+per.getProperty("BJ"));
 }
}

也可以存在XML文件之中

  File file=new File("D:"+File.separator+"area.xml");//指定要操作的文件

也可以讀取XML文件:

per.loadFromXML(new FileInputStream(file));//讀取屬性文件

屬性可以向普通文件或者XML文件保存或讀取,按照指定格式可以向文件中擴充屬性。

心態真的是被IE瀏覽器玩崩,一下午寫的東西被IE瀏覽器卡頓的一下就全沒了,以後些東西都再也不用IE瀏覽器了!!!!!!!!!

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