package mytest_object;
import java.util.Random;
/*
* 借助于接口,实现设计和使用分离(或者说:实现契约化设计)
* 思想是这样的,我们将一些功能抽象在接口中,在一个类中
* 调用这些功能方法(注意这些方法是空的,没有任何实现)来处理
* 问题(代码实现上就是,声明一个接口引用,然后用这个接口引用
* 来调用接口中抽象方法)。在另一个类中,我们来是实现接口中的
* 方法,然后通过运行多态性,让这个类的对象传递给功能定义类的
* 接口引用,这样那个接口引用就调用的是功能实现类的同名方法,这样
* 做的好处就是,只要实现类中相应的方法功能改变,那么功能定义类
* 的功能就会变动,即:向后兼容,或者说成是“以不变应对万变”
*/
interface Connector //接口是功能定义类和实现类的连接桥梁
{
void sortArray(int [] arr); //抽象的方法,预定义功能是对数组排序
}
/*测试排序方法,只要是实现了接口Connector的类的sortArray方法都可以被测试函数TestArray调用*/
class SortTest
{
private Connector con; //声明一个私有的Connector接口对象con
SortTest(Connector con) //这是与外界的接口,当传递不同的对象时,con就指向不同的对象
{
this.con=con;
}
public void testArray(int [] arr,int number)
{
/*
测试数组排序,arr是要测试的数组,number是测试次数
要想看看程序的正确与否,手动的输入几个数看排序结果不是太好,也麻烦,所以干脆写个测试函数,让他完成
测试的方法:随机产生伪随机数,赋值给数组,即随机得到一个数组,然后排序。再显示,以查看排序效果
这里讲数组让调用者以参数的形式传递主要是为了,让调用者控制数组的大小和测试的次数。其实这个测试次数参数
也可以根据数组的长度来让程序决定,但是这样久不灵活了。
*/
Random rd=new Random();
int num=0;
while(number>num)
{
//随机给数组arr赋值
for(int i=0;i<arr.length;i++)//随机的给数组赋值,也就是随机的得到一个整型数组
{
arr[i]=rd.nextInt(10*arr.length); //产生一个10*arr.length以内的整数值
}
//给数组arr排序
System.out.print(num+"次测试\n排序前:");
showArray(arr);//输出
con.sortArray(arr); // con指向那个对象,就调用那个对象的sortArray方法
//判断排序的准确确性
System.out.print("排序后:");
showArray(arr);//输出
System.out.println(isSortArray(arr)); //判断当前数组是否有序
System.out.println();
num++;
}
}
public boolean isSortArray(int [] arr)
{
/*
工具函数,判断一个数组是否有序
需要特殊处理的地方:
1.空数组或只有一个元素的数组有序
2.所有元素一样的情况
*/
if(arr.length<=1) //规定:空数组或只有一个元素的数组有序
{
return true;
}
else if(arr[0]==arr[arr.length-1]) //所有元素一样的情况
{
for(int i=0;i<arr.length-1;i++)
{
if(arr[i]!=arr[i+1])//如果存在不相等的元素,则表示无序
{
return false;
}
}
return true;//for中没有退出表示有序
}
else if(arr[0]<arr[arr.length-1])//判断一个序列是否由小到大有序
{
for(int i=0;i<arr.length-1;i++)
{
for(int j=i+1;j<arr.length;j++)
{
if(arr[i]>arr[j])//如果存在前大后小的情况,则无序
{
return false;
}
}
}
return true;//在for中没有结束。表示序列有序
}
else if(arr[0]>arr[arr.length-1])//判断序列是否由大到小有序
{
for(int i=0;i<arr.length-1;i++)
{
for(int j=i+1;j<arr.length;j++)
{
if(arr[i]<arr[j])//如果存在前小后大的情况,则无序
{
return false;
}
}
}
return true;//在for中没有结束。表示序列有序
}
return false;
}
public void showArray(int [] arr)//显示数组
{
//工具函数,显示数组元素用
for(int i=0;i<arr.length;i++)
{
System.out.print(arr[i]+"\t");//按行输出 每个元素,元素之间隔一个制表符空位
}
System.out.println();//换行
}
}
/* 主类实现Connector接口*/
public class MyObjectTest13 implements Connector
{
public void sortArray(int [] arr)//实现接口Connector的sortArray方法
{
//由小到大排序:选择排序法
int index=0; //记录当前序列中最小值元素的的下标
int temp; //临时变量,交换元素时用
for(int i=0;i<arr.length-1;i++) //控制趟数 length-1 趟
{
index=i; //每趟比较初始化(清零),这是容易弄错的地方
for(int j=i+1;j<arr.length;j++) //控制每趟的比较次数 length-i-1次 每趟比较选择出当前序列中最小的元素
{
/*这里千万要记住,是拿arr[index]比较的,而不是arr[i],因为是要拿当前找到的最小的元素去和它后面的元素比较的 */
if(arr[index]>arr[j]) //如果大的在前,则记录下比他小的值的下标
{
index=j;//记录下当前序列中的最下值的下标,注意arr[index]也是变动的
}
}
//本趟比较结束 ,交换:arr[index]是本趟比较得到的最小数 将它与当前元素arr[i]交换
if(index!=i)//比较i index防止没有需要交换的值的影响 如果index!=i说明有需要交换的值
{
temp=arr[i];
arr[i]=arr[index];
arr[index]=temp;
}
}
}
public static void main(String[] args)
{
int arr[]=new int [10];
/*
实例化对象,注意SortTest实例化需要传递一个Connector类型的参数
这里传递的是其实现类MyObjectTest13的一个对象,即多态的应用
*/
SortTest st=new SortTest(new MyObjectTest13());
/* 掉用SortTest类的TestArray方法测试MyObjectTest13类的sortArray方法 关键语句:con.sortArray*/
st.testArray(arr, 5);
}
}
|