数组的排序
快速排序
属于经典的十大排序中的一种,由图灵奖获得者 Hoare 研发出来的,它是平均时间复杂度最好的一种算法;
因为快速排序使用了一种叫做分治法的思想;
原理
① 先将数组内的任意一个元素设置为基准数 pivot
② 给数组新增两个指针 i,j;i从左往右开始移动,j从右往左开始移动
③ 当i 遇到比基准数大的数据时停下,i停下后让j指针开始移动,当j指针所指的数据小于pivot时停下
④ 当2个指针都停下后,比较 i 和 j 的大小。如果i < j ; 交换 i 指针和 j 指针所对应的数据,然后继续移动两个指针
⑤ 一直到两个指针停下时 ,并且此时 i >= j;这个时候就进行基准数和 j 指针所指的数据进行交换。
⑥ 基准数和 j 指针数据交换后,及是一趟的快速排序,此时基准数就是最终的位置
⑦ 多次递归的调用快速排序的方法,最终就能实现数组的快速排序
代码实现
public class QuickSort {
public static void main(String[] args) {
int[] arr = {23,25,9,88,64,101,70,66};
System.out.println(Arrays.toString(arr));
quick(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
public static void swap(int[] arr,int x,int y){
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
public static void quick(int[] arr,int start,int end){
if(start < end) {
int pivot = arr[start];
int low = start,high = end;
while(true){
// 让low指针开始向右移动,当所指的数据大于 pivot 的时候停下
while( low < end && arr[low] <= pivot){
low ++;
}
// 让 high 指针开始向左移动,当所指的数据小于 pivot 的时候停下
while( high > start && arr[high] >= pivot){
high --;
}
if( low < high){
swap(arr,low,high);
}else{
break;
}
}
swap(arr,start,high);
quick(arr,start,high-1);
quick(arr,high+1,end);
}
}
}
模板方法设计模式--抽象类应用
设计模式 -- "套路"
通过在大量实践中去总结和理论化后优选出来的一种代码结构,编程风格,以及解决问题的方式方法;好的设计模式可以让编程人员免掉大量的思考和摸索;就像下棋一样,有棋谱,遇到不同的棋局可以选择不同的棋谱
模板方法设计模式
① 概念:在方法内部设计一个算法的骨架,并将算法的一些步骤延迟到子类中去实现,使得子类可以不改变骨架的情况下定义某些算法的步骤
② 模式的结构
a. 抽象类---父类: 负责给出一个算法的轮廓,包含了一个模板方法和若干基本方法,还可以有钩子方法模板方法:定义算法的骨架,按照某种固定的顺序(步骤)去调用基本方法;该方法一般使用 final 来修饰, 防止子类对其进行重写
基本方法:模板方法中某一个步骤
1. 抽象方法: 算法中的易变部分,交给子类来实现
2. 普通方法: 算法中固定部分, 子类可以进行重写
3. 钩子方法: 通常是一个boolean 的返回值,可以用力作为算法中某个步骤的前提条件
b. 普通类---子类用来对父类中定义的算法骨架中,易变的部分进行重写(抽象方法/钩子方法)
案例:去银行取钱
思路
① 取号/排队
② 插卡/输入密码
③ 取钱
④ 取卡/满意度评价
代码实现
public abstract class Model_Method {
// 模板方法
public final void model_method(){
// 去调用基本方法
getNum();
insert_card();
in_password();
if(hook()){
getMoney();
comment();
}else{
System.out.println("余额不足,请取走您的卡片");
}
}
// 基本方法
public void getNum(){
System.out.println("取号");
}
public void insert_card(){
System.out.println("插卡");
}
// 抽象方法--表示易变的步骤
public abstract void in_password();
public abstract void getMoney();
public void comment(){ System.out.println("10分");
};
// 钩子方法
public boolean hook(){
return true;
}
}
public class Person_1 extends Model_Method{
double money = 1000;
double money_1;
public Person_1(double money_1){
this.money_1 = money_1;
}
@Override
public void in_password() {
System.out.println("密码是:123456");
}
@Override
public void getMoney() {
System.out.println("取钱金额:"+money_1+",余额为"+(money - money_1));
}
public boolean hook(){ if(money_1 > money){ return false;
}else{
return true;
}
}
}
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入取款金额:");
int money = scanner.nextInt();
Person_1 p1 = new Person_1(money);
p1.model_method();
}
}
接口--多态的实例应用
接口概念
指的是方法的集合,接口内部全部都是抽象方法,不存在普通方法;实际上接口就是制定一些规则
接口的特点(jdk1.8以前)
① 接口中没有成员变量,也没有构造方法,所有的变量在接口中都默认为静态常量
② 接口中所有的方法都是抽象方法,如果有实现类来实现接口,在实现类中强制要求重写所有的抽象方法
③ 在jdk1.8版本时规定了,接口中允许出现 default 和 static 修饰普通方法
④ 接口和抽象类一样不能直接被实例化(因为他们内部都有未实现的抽象方法)
⑤ 一个类可以同时实现( implements )多个接口(为了弥补java单继承的缺陷),接口与接口之间可以多继承
接口的定义
① 使用 interface 来定义接口
② 定义的格式:
public interface 接口名{
静态常量 --- 只能是常量,,如果按照声明变量的方式定义,系统会默认在变量的前面加上 public static final
抽象方法; --- 如果方法声明时没有有访问权限修饰词,系统会默认加上 public abstract
}
案例一 ---- 直接使用匿名内部类创建实现类对象
public interface Phone {
// 给谁打电话
void call();
// 显示手机品牌信息
void show_message();
// 铃声是什么
void music();
}
public class Test_Interface {
@Test
public void test1(){
new Phone(){
@Override
public void call() {
System.out.println("给塞班打电话");
}
@Override
public void show_message() {
System.out.println("我是诺基亚");
}
@Override
public void music() {
System.out.println("滴滴滴");
}
};
}
}
案例二 ---- 以接口作为方法参数并且体现多态的应用
public interface Animal {
void sayHello();
}
public class Test_Interface {
public void sayHello(Animal a){
a.sayHello();
}
@Test
public void test2(){
// 当我调用 sayHello 方法时打印 "旺旺旺" // sayHello(new Dog());
sayHello(new Animal() {
@Override
public void sayHello() {
System.out.println("喵喵喵");
}
});
}
}
抽象类和接口的区别
相同点
① 都不能直接实例化
② 都可以存在抽象方法(抽象类可以没有)
③ 都可以使用匿名内部类快速实现实例化
不同点
① 接口不能有变量只能有常量,抽象类可以有变量,可以存在常量
② 接口没有构造方法,抽象类有构造方法
③ 声明的关键字不同,声明抽象类使用 abstract ,声明接口使用 interface
④ jdk1.8以前接口中全是抽象方法,抽象类中可以存在普通方法
⑤ 抽象类只能继承而且是单继承,接口是被实现,可以多实现
⑥ 类与类之间只能是继承关系,接口与接口之间不能有实现关系,也只能是继承关系
⑦ 抽象类可以实现接口,接口不能继承抽象类
API简介 jar包制作
API
全称 application pregramming interface,应用程序接口,里面包含了很多别人写好的工具类(Math/Arrays)和常用的类(String/集合/线程)
使用IDEA制作jar包