java程序設計--孫鑫java無難事Lesson6《數組相關操作、幾個特殊的類、設計模式》

java程序設計--孫鑫java無難事Lesson6《數組相關操作、幾個特殊的類、設計模式》
本節要點:
1.數組的相關操作
2.封裝類
3.Runtime類與Process類
4.Class類
5.設計模式
詳細內容:
1.數組的相關操作

(1)基本類型的數組元素拷貝

測試代碼如下:

//*******************************************************************************

int[] num1=new int[]{1,2,3};
int[] num2=new int[10];
//System.arraycopy(num1,0,num2,0,num1.length);//ok
System.arraycopy(num1,0,num2,7,num1.length);//ok   if 8 error    參數是相關的
System.arraycopy(num1,0,num2,8,2);//ok
for(int i=0;i<num2.length;i++)
    System.out.println(num2[i]);
(2)對象數組的拷貝

測試代碼如下:

//*******************************************************************************

Point pts1[]=new Point[]{new Point(1,1),new Point(2,2),new Point(3,3)};
Point pts2[]=new Point[3];
System.arraycopy(pts1,0,pts2,0,pts1.length);//複製的是對象的引用   同一內存
for(int i=0;i<pts2.length;i++)
    System.out.println("x="+pts2[i].x+","+"y="+pts2[i].y);
pts2[1].x=5;
pts2[1].y=5;
System.out.println("x="+pts1[1].x+","+"y="+pts1[1].y);//pts1數據被修改 5,5
(3)數組排序和元素查找

注意,當自定義的類沒有實現Comparable 接口時無法排序,錯誤信息如下:

//*******************************************************************************

Exception in thread "main" java.lang.ClassCastException: Student cannot be cast
to java.lang.Comparable
        at java.util.ComparableTimSort.countRunAndMakeAscending(Unknown Source)
        at java.util.ComparableTimSort.sort(Unknown Source)
        at java.util.ComparableTimSort.sort(Unknown Source)

數組排序測試代碼如下:

//*******************************************************************************

//數組元素排序與查找

        int[] num=new int[]{3,1,2};
        Arrays.sort(num);//靜態方法
        for(int i=0;i<num.length;i++)
            System.out.println(num[i]);
        int index=Arrays.binarySearch(num,2);//已經排序的數組中查找
        if(-1!=index)
        {
            System.out.println("data found!");
            System.out.println("index="+index+",data="+num[index]);

        }

//*******************************************************************************

//運行結果

1
2
3
data found!

index=1,data=2

//*******************************************************************************

對象數組的排序和查找測試代碼如下:

//*******************************************************************************

class Student implements Comparable
{
    String name;
    int num;
    Student(String name,int num)
    {
        this.name=name;
        this.num=num;
    }
    public String toString()
    {
       return "num="+num+",name="+name;
    }
    public int compareTo(Object o)
    {    
        Student stu=(Student)o;
        int ret= num>stu.num?1:(num==stu.num?0:-1);
        //序號相同時繼續名字排序
        if(0==ret)
        {
           ret=name.compareTo(stu.name);
        }
        return ret;
    }
}
class ArrayTest
{
    public static void main(String[] args)
    {

    Student[] students=new Student[]{new Student("ZhangSan",1),new Student    ("LiSi",2),new     Student

("ZhaoEr",3),new Student("WangWu",3)};
     Arrays.sort(students);
    for(int i=0;i<students.length;i++)
    System.out.println(students[i]);
    int index=Arrays.binarySearch(students,new Student("LiSi",2));//已經排序的數組中查找
    if(-1!=index)
    {    
      System.out.println(students[index]);
    }

}

//*******************************************************************************

//運行結果
num=1,name=ZhangSan
num=2,name=LiSi
num=3,name=WangWu
num=3,name=ZhaoEr
num=2,name=LiSi
2.封裝類
針對八種基本數據類型定義的相應的引用類型-封裝類。

封裝類如下圖所示:


封裝類測試代碼如下:

//*******************************************************************************

class Test
{
    public static void main(String[] args)
    {   
        int i=3;
        Integer in=new Integer(i);//封裝類內容不允許修改其內容
        int j=in.intValue();
        System.out.println("j="+j);
        String str=in.toString();
            System.out.println("str="+str);
        String str2="123";
        System.out.println(Integer.valueOf(str2));
            System.out.println(Integer.parseInt(str2));
    }
}
3.Runtime類與Process類
(1)Runtime類的特點:

a.每一個Java程序都有一個Runtime類的單一實例。

b.通過Runtime.getRuntime()獲取Runtime類的實例。

c.Runtime類是使用單例模式的一個例子。
(2)通過Runtime類的方法開啓新進程執行其他任務,該新進程通過返回的Process對象來控制.

測試代碼如下:

//*******************************************************************************

import java.io.*;
class RuntimeTest
{
    public static void main(String[] args)
    {   
        Runtime rt=Runtime.getRuntime();//僅能獲取一個唯一實例
        System.out.println(rt.freeMemory());
        System.out.println(rt.totalMemory());
        try
        {
            //rt.exec("notepad");//打開記事本
             rt.exec("javac ArrayTest.java");//編譯源文件
             Process ps=rt.exec("java ArrayTest");//運行類文件並保存進程對象
             //將結果顯示到當前輸出窗口
             InputStream is=ps.getInputStream();
             int data;
             while((data=is.read())!=-1)
             {
                System.out.print((char)data);
             }
        }
        catch (Exception e)
        {
            System.out.println(e.toString());
        }
    }

}

//*******************************************************************************

//運行結果
15725992
16252928
num=1,name=ZhangSan
num=2,name=LiSi
num=3,name=WangWu
num=3,name=ZhaoEr
num=2,name=LiSi
4.Class類
(1)什麼是Class類
在Java中,每個class都有一個相應的Class對象。也就是說,當我們編寫一個類,編譯完成後,
在生成的.class文件中,就會產生一個Class對象,用於表示這個類的類型信息.
(2)獲取Class實例的三種方法
a.利用對象調用getClass()方法獲取該對象的Class實例;
b.使用Class類的靜態方法forName(),用類的名字獲取一個Class實例;
c.運用.class的方式來獲取Class實例,對於基本數據類型的封裝類,
還可以採用.TYPE來獲取相對應的基本數據類型的Class實例。

獲取Class類的測試代碼:

//*******************************************************************************

class ClassTest
{
    public static void main(String[] args)
    {   
        /*
        Point pt=new Point(3,4);
        Class cl=pt.getClass();
        System.out.println(cl.getName());
        try
        {
            Class cl2=Class.forName("Point");
            System.out.println(cl2.getName());
        }
        catch(ClassNotFoundException e)
        {
           System.out.println(e.toString());
        }
        Class cl3=Point.class;
        System.out.println(cl3.getName());

        Class cl4=int.class;
        System.out.println(cl4.getName());

        Class cl5=Integer.TYPE;
        System.out.println(cl5.getName());

        Class cl6=Integer.class;
        System.out.println(cl6.getName());

}

//*******************************************************************************

//運行結果
Point
Point
Point
int
int
java.lang.Integer
(3)類加載時間
在運行期間,如果我們要產生某個類的對象,Java虛擬機(JVM)會檢查該類型的Class對象是否已被加載。如果沒有被加載,JVM會根據類的名稱找到.class文件並加載它。一旦某個類型的Class對象已被加載到內存,就可以用它來產生該類型的所有對象。

通過靜態代碼的執行時間來反映類加載時間,測試代碼如下:

//*******************************************************************************

class Point
{
    int x,y;
    Point(int x,int y)
    {
       this.x=x;
       this.y=y;
    }
    //靜態代碼段
    static
    {
       System.out.println("Loading Point!");
    }
    void outPut()
    {
       System.out.println("x="+x+"y="+y);
    }
}
class Line
{
    static
    {
       System.out.println("Loading Line!");
    }
}
class ClassTest
{
    public static void main(String[] args)
    {
        System.out.println("before new Point!");
        new Point(3,4);
              System.out.println("after new Point!");
        try
        {
            Class.forName("Line");
        }
        catch(ClassNotFoundException e)
        {
           System.out.println(e.toString());
        }

}       

//*******************************************************************************

//運行結果
before new Point!
Loading Point!
after new Point!
Loading Line!
(4)反射API動態創建實例

測試代碼如下:

//*******************************************************************************

//動態創建對象 並獲取其構造函數和方法
        if(args.length!=1)
            return;
        try
        {
            Class cl=Class.forName(args[0]);
            Constructor[] cs=cl.getDeclaredConstructors();
            for(int i=0;i<cs.length;i++)
                System.out.println(cs[i]);
             Method[] m=cl.getDeclaredMethods();
             for(int i=0;i<m.length;i++)
                System.out.println(m[i]);
        }
        catch(Exception e)
        {
            e.printStackTrace();

        }

//*******************************************************************************

//運行結果
F:\java\JavaLesson\Lesson6>java ClassTest Point
Loading Point!
Point(int,int)
void Point.outPut()
(5)動態創建實例時判斷構造函數的方法

Class類的newInstance方法將調用類中缺省的構造方法,當缺少缺省構造函數時,會出錯,錯誤信息如下:

//*******************************************************************************

F:\java\JavaLesson\Lesson6>java ClassTest Point
Loading Line!
Loading Point!
java.lang.InstantiationException: Point
        at java.lang.Class.newInstance0(Unknown Source)
        at java.lang.Class.newInstance(Unknown Source)
        at ClassTest.main(ClassTest.java:65)
        at java.util.Arrays.sort(Unknown Source)
        at ArrayTest.main(ArrayTest.java:41)
解決方法:先獲取構造方法和相應的參數信息,然後動態創建實例.

測試代碼如下:

//*******************************************************************************

if(args.length!=1)
            return;
        try
        {
            Class cl=Class.forName(args[0]);
            Constructor[] cs=cl.getDeclaredConstructors();
            //已知只有一個構造函數
            Class[]    params=cs[0].getParameterTypes();
            Object[]  paramValues=new Object[params.length];
            for(int i=0;i<params.length;i++)
            {
                 if(params[i].isPrimitive())
                {
                   paramValues[i]=new Integer(i+3);
                 }
            }
            Object ob=cs[0].newInstance(paramValues);
            //已知只有一種方法且方法無參數
            Method[] m=cl.getDeclaredMethods();
            m[0].invoke(ob,null);
        }
        catch(Exception e)
        {
           e.printStackTrace();

        }

//*******************************************************************************

//運行結果
F:\java\JavaLesson\Lesson6>java ClassTest Point
Loading Point!
x=3y=4    
5.設計模式
什麼是設計模式:
在我們進行程序設計時,逐漸形成了一些典型問題和問題的解決方案,這就是軟件模式。
每一個模式描述了一個在我們程序設計中經常發生的問題,以及該問題的解決方案。爲什麼需要設計模式:
當我們碰到模式所描述的問題,就可以直接用相應的解決方法去解決這個問題,這就是設計模式。
關於設計模式需要更進一步的學習。

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