java程序设计--孙鑫java无难事Lesson6《数组相关操作、几个特殊的类、设计模式》

来源:互联网 发布:mac 手绘 编辑:程序博客网 时间:2024/05/16 18:26
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.设计模式
什么是设计模式:
在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式。
每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案。为什么需要设计模式:
当我们碰到模式所描述的问题,就可以直接用相应的解决方法去解决这个问题,这就是设计模式。
关于设计模式需要更进一步的学习。