14、泛型與其他API

十四、泛型與其他API

1、系統結構圖(xmind)

——泛型:

——2.其他API


2、tips

——1.泛型

1.JDK1.5的集合類希望在定義集合時,明確表明你要向集合中裝入那種類型的數據,無法加入指定類型以外的數據

2.泛型是提供給javac編譯器使用的可以限定集合中的輸入類型說明的集合時,會去掉“類型”信息,使程序運行效率不受影響,對參數化的泛型類型,getClass()方法的返回值和原始類型完全一樣。

3.由於編譯生成的字節碼會去掉泛型的類型信息,只要能跳過編譯器,就可以往某個泛型集合中加入其它類型的數據,如用反射得到集合,再調用add方法即可。

4.沒有使用泛型時,只要是對象,不管是什麼類型的對象,都可以存儲進同一個集合中。使用泛型集合,可以將一個集合中的元素限定爲一個特定類型,集合中只能存儲同一個類型的對象,這樣更安全;並且當從集合獲取一個對象時,編譯器也可以知道這個對象的類型,不需要對對象進行強制類型轉換,這樣更方便。泛型就是把原來的類名進行了延長!在JDK 1.5中,你還可以按原來的方式將各種不同類型的數據裝到一個集合中,但編譯器會報告unchecked警告。

5.通常在集合框架中很常見,只要見到<>就要定義泛型。其實<>就是用來接收類型的。當使用集合時,將集合中要存儲的數據類型作爲參數傳遞到<>中即可。

6.編譯器不允許創建泛型變量的數組。即在創建數組實例時,數組的元素不能使用參數化的類型,如:Vector<Integer>vectorList[] = new Vector<Integer>[10];//錯誤的。

7.Collection<?>  a可以與任意參數化的類型匹配,但到底匹配的是什麼類型,只有以後才知道,所以:a=newArrayList<Integer>和a=new ArrayList<String>都可以,但a.add(new Date())或a.add(“abc”)都不行。

8.語法格式:

       class Utils<XX>
      {
             private XX s;
             public void setxx(XX s)
            {
                 this.s=s;
             }
             public XX getXX()
             {
                 return s;
             }
       }


總結:

對泛型的定義:

第一、定義泛型:當又不確定的類型需要傳入到集合中,需要定義泛型。

第二、定義泛型類:如果類型確定後,所操作的方法都是屬於此類型,則定義泛型類。

第三、定義泛型方法:如果定義的方法確定了,裏面所操作的類型不確定,則定義泛型方法。


——2.編譯器的泛型

1、編譯器判斷範型方法的實際類型參數的過程稱爲類型推斷,類型推斷是相對於知覺推斷的,其實現方法是一種非常複雜的過程。

2、根據調用泛型方法時實際傳遞的參數類型或返回值的類型來推斷,具體規則如下:

      1)當某個類型變量只在整個參數列表中的所有參數和返回值中的一處被應用了,那麼根據調用方法時該處的實際應用類型來確定,這很容易憑着感覺推斷出來,即直接根據調用方法時傳遞的參數類型或返回值來決定泛型參數的類型。

                  慄:swap(new String[3],3,4)

                         ——>    static <E> voidswap(E[] a, int i, int j)

      2)當某個類型變量在整個參數列表中的所有參數和返回值中的多處被應用了,如果調用方法時這多處的實際應用類型都對應同一種類型來確定,這很容易憑着感覺推斷出來

                  慄:add(3,5)

                         ——>   static<T> T add(T a, T b)

      3)當某個類型變量在整個參數列表中的所有參數和返回值中的多處被應用了,如果調用方法時這多處的實際應用類型對應到了不同的類型,且沒有使用返回值,這時候取多個參數中的最大交集類型,例如,下面語句實際對應的類型就是Number了,編譯沒問題,只是運行時出問題:

                  慄:fill(new Integer[3],3.5f)

                         ——>    static<T> void fill(T[] a, T v)


      4)當某個類型變量在整個參數列表中的所有參數和返回值中的多處被應用了,如果調用方法時這多處的實際應用類型對應到了不同的類型,並且使用返回值,這時候優先考慮返回值的類型,例如,下面語句實際對應的類型就是Integer了,編譯將報告錯誤,將變量x的類型改爲float,對比eclipse報告的錯誤提示,接着再將變量x類型改爲Number,則沒有了錯誤:

                  慄: intx =(3,3.5f)

                         ——>   static<T> T add(T a, T b)

      5)參數類型的類型推斷具有傳遞性,下面第一種情況推斷實際參數類型爲Object,編譯沒有問題,而第二種情況則根據參數化的Vector類實例將類型變量直接確定爲String類型,編譯將出現問題:

                  慄: copy(newInteger[5],new String[5])

                         ——>   static<T> void copy(T[] a,T[]  b);

                          copy(newVector<String>(), new Integer[5])

                         ——>   static<T> void copy(Collection<T> a , T[] b);

——3.實例

import java.util.*;

//人  父類
class Person
{
	private String name;
	Person(String name)
	{
		this.name = name;
	}
	public String getName()
	{
		return name;
	}
}
//學生  繼承父類
class Student extends Person
{
	Student(String name)
	{
		super(name);
	}
}

class  Demo
{
	public static void main(String[] args) 
	{
		ArrayList<Person> al = new ArrayList<Person>();
		al.add(new Person("abc1"));
		al.add(new Person("abc2"));
		al.add(new Person("abc3"));
		printColl(al);//父類對象的元素集合可以調用

		ArrayList<Student> al1 = new ArrayList<Student>();
		al1.add(new Student("abc--1"));
		al1.add(new Student("abc--2"));
		al1.add(new Student("abc--3"));
		printColl(al1);  //子類對象的元素集合也可以調用
	}

//定義一個上限的泛型方法
public static void printColl(Collection<? extends Person> al)
	{
		Iterator<? extends Person> it = al.iterator();
		while(it.hasNext())
		{
			System.out.println(it.next().getName());
		}
	}
}


——4.System類

1、字段摘要
       out:標準輸出流。默認是控制檯。
       in:標準輸入流。默認是鍵盤。
2、方法
       1)獲取系統的屬性信息:PropertiesgetProperties();。
       2)說明:
             1.此方法返回的雙列集合,即鍵值對;因爲Properties是Hahstable的子類,也就是Map集合的一個子類對象,那麼通過Map方法取出該集合中的元素。
             2.該集合存儲的都是字符串,沒有泛型定義。
       3)獲取指定屬性信息:String getProperty(Stringkey);。
       4)在系統內定義特有信息:String setProperty(Stringkey,String value);。
       5)如何在jvm啓動時,加載一些屬性信息:通過命令:java -D<name>=<value>可以設置特有的系統屬性信息。

——5.Runtime類

1、該類中並沒有提供構造函數。說明不可以new對象。那麼會直接想到該類中的方法都是靜態的。查閱API文檔發現,該類中還有非靜態方法。說明該類肯定會提供了方法獲取本來對象。而且該方法是靜態的,並返回值類型是本來類型。由以上特點可以看出該類使用了單例設計模式完成。
2、方法
        1)獲取本類對象 :static RuntimegetRuntime();
        2)在單獨的進程中執行指定字符串命令:Processexec(String command);
        3)在Process中有一個殺掉子進程的方法,可將exec方法開啓的進程結束:void destroy();

——6.Date類
1.  Date類表示特定的瞬間,精確到毫秒。
     java中的默認顯示格式爲:Mon Jun 10 22:35:21 CST2013           
2、自定義格式
        默認的格式不一定滿足每個人的需求,那麼就需要自定義格式化模式。因爲Date類中的大部分方法已過時,所以只能找其子類來實現。子類DateFormat中有format方法可以實現,但是DateFormat是抽象類,不能實例化。但是其下有個SimpleDateFormat子類,可以定義時間模式。
具體步驟:
        1)創建Date對象
        2)將時間模式封裝到SimpleDateFormat對象中
        3)調用format方法讓格式化模式指定Date對象

——7.Calendar類

方法:

1、基本獲取時間
        1)獲取年份:Calendar.YEAR
        2)獲取月份:Calendar.MONTH
        3)獲取日期:Calendar.DAY_OF_MONTH
        4)獲取星期:Calendar.DAY_OF_WEEK
        5)獲取小時:Calendar.HOUR_OF_DAY
        6)獲取分鐘:Calendar.MINUTE
        7)獲取秒數:Calendar.SECOND
2、設置時間:
        1)根據日曆的規則,爲給定的日曆字段添加或減去指定的時間量:
                void add(int field,int amount);
        2)獲取指定的日曆字段對應的時間值:
                int get(int field);

        3)將給定日曆字段對應的時間值設置爲給定值:
                void set(int field,int value);
       設置日曆字段 YEAR、MONTH和DAY_OF_MONTH的值:
                void set(int year,int month,int date);
慄:
/**
 * 需求:編寫程序,該程序啓動後用戶可以按“yyyy-MM-dd”的格式輸入一個日期,程序計算這一
 * 天是星期幾,並且計算出是一年中的第幾天。
 */
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Scanner;
import java.util.Date;

class DateDemo
{
	public static void main(String[] args)throws Exception
	{
		//運用scanner接收鍵盤輸入
		Scanner sc = new Scanner(System.in);
		System.out.print("請輸入日期(格式爲yyyy-MM-dd):");
		OutputDate(sc);
		sc.close();
	}
	
	public static void OutputDate(Scanner sc)throws Exception
	{
		//定義格式
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		//scanner獲取的格式進行解析存入d這個日期值中
		Date d = sdf.parse(sc.next());
		//定義一個Calendar日曆用於獲取需要的兩個值
		Calendar cd = Calendar.getInstance();
		//將需要輸出的時間值存於日曆中
		cd.setTime(d);
		//獲取並輸出星期
		getWeek(cd);
		
		System.out.println(",是今年的第"+cd.get(Calendar.DAY_OF_YEAR)+"天。");
	}

	public static void getWeek(Calendar cd)
	{
		//獲取星期的值用於查找表相對應的字符串並輸出
		int num = cd.get(Calendar.DAY_OF_WEEK);
		String[] week = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
		System.out.print("今天是:"+week[num-1]);
	}
}

運行結果:


——8.Math類
方法:
        1、doubleceil(double d);//返回大於指定數據的最小整數
        2、doublefloor(double d);//返回小於指定數據的最大整數
        3、double pow(doublea,double b);//返回a的b次方
        4、long round(doubleb);//返回b四捨五入的值
        5、doublerandom();//返回正號的double值,是一個大於等於0.0且小於1.0的隨機數

三、Random類
        這是java.util中的一個單獨的類,該類對象用於獲取隨機數。與Math中的random方法是一樣的,不過這個類有自身的方法,可以將相應的隨機數強轉爲指定基本數據類型。







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