Java Day21

总结

目录
选择排序算法推导 2
一 找出数组中最大值,和下标为0的元素互换位置; 2
二 接上一题, 找出数组中剩余数据最大值,和下标为1的元素互换位置; 3
三 接上一题, 找出数组中最大值,和下标为2的元素互换位置 4
【直到第九题,找最大值和下标8换位置,(此时数组中只剩下两个数还未排序)此时就完成了将数组中十个数从大到小顺序排列】*/ 4
实现代码 4
找出数组中指定元素的所有下标位置 7
循环 scannner 方法 知识点融合(顾客点菜) 13
值传递图解 14
十分钟 18
循环嵌套 19
方法 19
方法的意义和实现 19
方法调用 20
方法返回值 21
局部变量 23
数组 24
创建数组的方式 24
引用数据类型 26
数组地址转移问题【难点】 26
数组作为方法的参数 28
代码运行中是否有需要考虑的异常情况?比如以下越界问题 33
用户指定的下标位置,超出的有效位置 33
参数合法性判断要放在方法内, 33
同时,也无需多写,这个方法该干嘛就只写实现这个功能的代码,不该它做的事情就不写进去. 比如只是查找下标就不用吧打印也写进去,具体查找到下标后的下一步就交给这个方法以外的其他代码来实现 33

第二周学习总结
选择排序算法推导
一 找出数组中最大值,和下标为0的元素互换位置;
int[] arr = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};

找出数组中的最大值下标位置

int index = 0;
for (int i = 1; i < arr.length; i++) {
if (arr[index] < arr[i]) {
index = i;
}
}

if (index != 0) {
int temp = arr[0];
arr[0] = arr[index];
arr[index] = temp;
}
二 接上一题, 找出数组中剩余数据最大值,和下标为1的元素互换位置;
int index = 1;

从下标为1的位置开始找出最大值的下标位置
【数组中0下标元素在题目一中已经是最大值,所以从1开始】
for (int i = 2; i < arr.length; i++) {
if (arr[index] < arr[i]) {
index = i;
}
}

if (index != 1) {
int temp = arr[1];
arr[1] = arr[index];
arr[index] = temp;
}
三 接上一题, 找出数组中最大值,和下标为2的元素互换位置
【直到第九题,找最大值和下标8换位置,(此时数组中只剩下两个数还未排序)此时就完成了将数组中十个数从大到小顺序排列】*/
实现代码
/**

  • 选择排序算法
  • @author Anonymous

/
public class XvanZePaiXv {
public static void main(String[] args) {
int[] arr = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 };
selectSort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
/
*
* 选择排序算法
*
* @param arr
*/
public static void selectSort(int[] arr) {
// 外层循环,控制需要进行核心操作的次数,次数是数据量 - 1
for (int i = 0; i < arr.length - 1; i++) {

		int index = i;        /*i = 0;从数组第一位查询; 
		                        i = 1;从第二位开始查询比较
		                       (因为第一位已经查询出来是最大值了)
			         可以看出规律 int index = i*/
		
		for (int j = i + 1; j < arr.length; j++) {	//用for比较找出最大值
			//找出最大值下标赋给index
			// if 之后是选择排序排序算法的核心
			if (arr[index] < arr[j]) {
				index = j;
				
			}
		}
		if (index != i) { 

index如果不等于i,再执行以下操作,否则不用,以此减少工作量 //错误
int temp = arr[i]; //int temp = arr[inddex]
arr[i] = arr[index]; //arr[i] = temp;
arr[index] = temp; //arr[index] = arr[i];
}
}
}
}
找出数组中指定元素的所有下标位置
/*找出数组中指定元素的所有下标位置
案例数组:
int[] arr = {1, 2, 3, 1, 2, 3, 1, 2, 3};
找出元素1 的所有下标位置
需要得到:
0, 3, 6
要求:
a. 不允许在方法内打印展示
b. 考虑多个数据情况
c. 需要在方法外获取到下标数据信息
d. 不允许使用数组作为返回值
e. 一个方法完成

目的:
1. 学会使用数组传递过程,保存必要的数据
2. 操作过程中会形成一个计数器思想
3. 形成一个标记性思想
4. 形成代码安全性判断思想,保证代码健壮性,安全性
思考: 需要返回值吗 返回什么内容?
返回值采用int类型,返回的数据时目标数组中有多少个找到元素
返回0,表示没有指定元素,返回值的大于等于1找到的个数
最大的问题:
找到的下标位置如何保存,然后让方法外可以得到
1. 下标首先是int类型
2. 下标可能存在多个

    这里貌似需要一个数组,int类型数组,保存下标位置
但是数组不能作为返回值
	这里有且只有一个途径,在参数中加入一个数组,
	用于保存找到的目标数据下标位置,这里传入的保存下标的
	数组可以在方法内使用,并且保存数据,方法外可以获取

问题继续分析
(int[] arr, int[] indexes, int find)
arr 是源数据数组
indexes 保存下标的数组
{0, 0, 0, 0, 0, 0, 0, 0}
indexes 下标为0的元素,如果保存的数据是0的情况下,
不能确定0是【有效数据】还是无效数据。
这里需要一个数据,来辅助我们确定当前indexes数组中有多少有效元素,
或者说找到了多少个指定元素。*/
public class HomeWork1 {
public static void main(String[] args) {
int[] arr = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
int[] indexes = new int[arr.length];

	// 接受方法的返回值,得到的数查询目标数据的个数
	int count = findAllIndex(arr, indexes, 1);
	
	if (count > 0) {
		for (int i = 0; i < count; i++) {
			System.out.println(indexes[i]);
		}
	} else {
		System.out.println("Not Found!");
	}
}

/*
 * indexes数组容量 == arr.length?
 * why???
 * 		1. 存在可能性目标数组中的所有元素都是指定需要查询的数据
 * 		2. 如果大于目标数组容量,浪费空间
 */
/**
 * 找出指定数组arr中,指定元素find所有的下标位置,保存到indexes数组中,返回值 是找到的目标数据个数
 * 
 * @param arr     查询数据的目标数组
 * @param indexes 保存下标信息的数组
 * @param find    指定的目标数据
 * @return 找到指定数据个数,返回0,表示没有找到,返回值大于0,找的元素个数
 */
public static int findAllIndex(int[] arr, int[] indexes, int find) {
	// 参数合法性判断
	if (indexes.length < arr.length) {
		// 输入参数不合法!!!
		System.out.println("Input Parameter is Invalid");
		// 参数不合法,方法结束,返回0,表示没有找到数据
		return 0;
	}
	
	/*
	 * 1. 计数,当前指定数组arr中,有多少个目标元素
	 * 2. count同时是indexes数组中下一次存放数据的下标位置
	 */
	int count = 0;
	
	// 遍历目标数组arr
	for (int i = 0; i < arr.length; i++) {
		// 如果发现了指定元素 find
		if (find == arr[i]) {
			/*
			 *  需要保存下标位置到indexes数组中
			 *  操作过程是需要讲indexes数组中存储下标位置
			 *  下标位置需要放入到下一个空余位置中,同时需要
			 *  完成计数操作
			 *  
			 *  count数据刚刚好就是下一次存储数据的位置下标
			 */
			indexes[count] = i;
			count++;
		}
	}
	
	return count;
}

}
循环 scannner 方法 知识点融合(顾客点菜)

import java.util.Scanner;

class Method1 {
public static void main(String[] args) {
int choose = 0;
int total = 0;

	Scanner sc = new Scanner(System.in);
	
	showMenu();
	do {
		choose = sc.nextInt();
		total += orderDishes(choose);

/*用户输入choose的值 把这个choose的值赋给 orderDishes中的choose(两个choose非同一个,见图解),然后根据choose的值返回对应的price的值;用do while循环以上操作,把所有price的和赋给total;最后输入6时输出tatal。 */
System.out.println(“总消费 :” + total);
值传递图解


}
/**
* 展示菜单
*/
public static void showMenu() {
	System.out.println("1.吃 85rmb");
	System.out.println("2.喝 86rmb");
	System.out.println("3.玩 87rmb");
	System.out.println("4.乐 88rmb");
	System.out.println("5.睡 89rmb");
	System.out.println("6.下单 ");
	
}
/**
* 根据用户的选择,返回对应的项目,选择6下单
*
* @param choose int数据类型,用户的选择
* @return 返回值是项目的价格,返回0表示用户退出选择
*/

public static int orderDishes(int choose) {
	int price = 0;
	switch (choose) {
		case 1:
		System.out.println("1.吃 85");
		price = 85;
		break;
		case 2:
		System.out.println("2.喝 86");
		price = 86;
		break;
		case 3:
		System.out.println("3.玩 87");
		price = 87;
		break;
		case 4:
		System.out.println("4.乐 88");
		price = 88;
		break;
		case 5:
		System.out.println("5.睡 89");
		price = 89;
		break;
		case 6:
		System.out.println("6.下单");
		break;
		default:
		System.out.println("选择错误");
		break;
		
	}
	return price;
}

}
十分钟

循环嵌套
拿到题目分步骤实现,先考虑外层,再考虑内层;先考虑这部分,再考虑下部分。找到(凑出)形成循环条件判断的公式,凑出的公式要有普适性
循环嵌套时要注意大括号关系,局部变量有时会因为所在大括号位置不对而使程序出错
方法
方法的意义和实现
开发中,存在代码需要复用的情况。虽然循环可以解决一部分代码复用的问题,但是无法从根本上解决需要多处使用的情况。
这里需要用到方法
代码中使用循环解决复用的问题
1. 代码冗余!!!
2. 维护性极差!!!
3. 阅读性极差!!!
方法三要素 返回值类型 方法名 形式参数列表
public static void printHelloWorld() {方法体}
固定格式public static 返回值 小驼峰方法名 (){方法体}
文档注释
/**

  • 该方法是传入两个int类型的数据,返回值是两数之和
  • @param num1 int类型数据
  • @param num2 int类型数据
  • @return 返回值类型为int类型,是两个int类型数据之和
    */
    方法调用
    方法是条狗,哪里需要哪里吼
    printHelloWorld()
    1. 在需要调用方法的位置,使用方法名调用方法
    2. 方法和变量的最大区别,方法后面一定有小括号!!!
      方法总结
  1. 目前我们有且只考虑在main方法中来调用其他方法

  2. main方法是目前我们现在程序的唯一入门,如果想要哪一个代码执行,哪一个方法被调用,都需要经过main方法完成

  3. 方法位置在class以内,其他方法之外
    4写好的方法需要参数,那么调用方法时必须给予对应的方法声明中的参数的个数,数据类型,顺序。
    5 声明时public static void printHelloWorld(形式参数列表int num)
    调用时printHelloWorld(实际参数10)。
    6 方法之间可以相互调用
    方法返回值
    返回值没有什么必要和不必要,需求分析过程!!!
    return
    方法中要尽量减少return出现的个数(增强阅读性),但是可以有多个return出现,但是只能有一个返回值。
    if (num1 > num2) {
    return num1;
    } else {
    return num2;
    }
    */

     /*  
     当前写法是没有问题,而且使用到假设的思想,可以提供代码的
     阅读性,并且简化代码逻辑,减少return使用
     
     int max = num1;
     
     if (max < num2) {
     	max = num2;
     }
     
     return max;
    

作用:
1. 结束当前方法的执行
2. 返回return之后的数据,到方法之外,要求返回值的数据和方法声明位置告知调用者的返回值数据类型一致
【数据类型一致化】
3 三目运算符/条件运算符
条件 ? true处理方式 : false处理方式;
简化版,功能缺失版 if else结构
建议:
在一些简单的逻辑中可以使用,提高一定的效率
*/
return num1 > num2 ? num1 : num2;
局部变量
局部变量概念
除class大括号之外,其他大括号以内的变量都可以认为是一个局部变量。
方法大括号以内,if分支结构以内,switch case结构大括号以内,循环大括号以内
以上大括号以内全部都是【局部变量】。
局部变量的生存期和作用域都在当前所处大括号以内,超出范围无法使用

  1. 关注局部变量的作用域和生存期范围,两者同步,并且都在对应的大括号以内
  2. 变量未定义不能使用,要保证代码执行的,从上至下,从左至右原则
    数组
  3. 存储位置一致,并且连续
    1. 有统一的称呼,方便管理
    2. 存在唯一索引,具有一定的唯一性
      创建数组的方式
      int[] array = new int[10]; 下标范围0-9.
      赋值号左侧:
      int:
      告知编译器,这里创建定义的是一个int类型数组,有且只能保存int类型数据,保
      证数据类型一致化
      []:
      1. 告知编译器,当前定义的数据类型是一个数组类型
      2. 数组名 array是一个【引用数据类型】
        array:
      3. 这里是一个数组名,操作数组的核心数据!!!就是一个变量名
      4. 数组名 array是一个【引用数据类型】

赋值号右侧:
new:
new关键字需要在计算机中申请【连续内存空间】,这块区域在内存的【堆区】
【生活案例】这里就好比,顾客找仓库管理员申请货架,管理员一定是给你一个整
个连续区域给你使用
int:
前后呼应,告知编译器这里能够存储的数据类型是int类型,其他类型都不可以,要
求数据类型一致化
[10]:
告知编译器,当前数组的【容量 Capacity】是多少,这里是10,也就是说当前数
组中有且只能保存10个int类型数据
操作格式:
数组名[有效下标]
数组关系极为密切是for循环!!!
for (int i = 0; i < arr.length; i++) {
// 给数组中每一个元素赋值操作
arr[i] = i + 1;
}
引用数据类型
开发中的【引用数据类型】,实际上是一个指向其他内存空间的一个数据类型。引用数据类型的变量中存储的内容是其他内存空间的【首地址】。
当CPU访问到【引用数据类型】变量时,会得到其存储的地址,然后直接跳转到对应的内存空间中,执行代码,获取数据,操作内容…
数组地址转移问题【难点】图
public static void main(String[] args) {
int[] arr1 = new int[10];
int[] arr2 = new int[10];

arr1[0] = 10;
arr2[0] = 20;

System.out.println("arr1[0]:" + arr1[0]);
System.out.println("arr2[0]:" + arr2[0]);

arr1[5] = 50;

arr2 = arr1;

arr1[0] = 30;
arr2[0] = 100;

System.out.println("arr1[0]:" + arr1[0]);
System.out.println("arr2[0]:" + arr2[0]);
System.out.println("arr2[5]:" + arr2[5]);
/*
1. 报错
2. 30 30 50 
3. 100 100 50 true

}
数组作为方法的参数
public static void main(String[] args) {

}

/*
(String[] args)
String[] args 就是给数组作为方法参数格式,这里main方法需要的参数是一个String 类型的数组

格式:
public static 返回值类型 方法名(数据类型[] 数组参数名)

数组是可以作为方法的返回值
【BUT】
在我没有演示,讲解数组作为返回值使用的情况下,任何人不得使用数组作为返回值
以防万一你遇到一些你想不到的错误!!!
方法验证和传参方式
class Demo2 {
public static void main(String[] args) {
int[] array = {10, 8, 35, 67, 31, 25, 11, 30, 28, 99};
int find = 13;

	// 调用的方法需要数组作为方法的参数,
	// 这里传入【数组名】
	int index = indexOf(array, find);
	
	if (index >= 0) {
		System.out.println("index : " + index);
	} else {
		System.out.println("Not Found!");
	}
}	

/**
* 在指定数组arr中,查询指定元素find所在的下标位置,找到返回值大于等于0,没有找到
* 返回-1
*
* @param arr  查询数据的源数据数组,int类型数组
* @param find 指定在数组中查询的数据,也是对应int类型
* @return 找到指定元素,返回值大于等于0,否则返回-1
*/
public static int indexOf(int[] arr, int find) {
	// 假设查询的数据不存在
	int index = -1;
	
	// 遍历整个数组
	for (int i = 0; i < arr.length; i++) {
		// 发现数组中下标为i的元素和find一致,找到内容,保存下标
		if (find == arr[i]) {
			index = i;
			// 终止循环
			break;
		}
	}
	
	// 返回index中保存的数据
	return index;
}

}

  1. 数组作为方法参数的固定格式
    (数据类型[] 数组参数名)
  2. 数组作为方法的实际参数的固定格式
    (数组名)
  3. 数组名作为方法的参数,实际传递的是数组空间首地址,就是和数组地址转移问题是一致的
  4. 方法执行需要参数,如果没有给予对应格式的实际参数,直接报错
    代码运行中是否有需要考虑的异常情况?比如以下越界问题
    用户指定的下标位置,超出的有效位置
    需要在代码中进行参数合法性判定!!!
    参数合法性判断要放在方法内, 而不能放在调用方法的位置,这也是方法实现功能的一部分(也可这样想如果你封装的方法多了 你总不能在main方法中 ,都写成合法性判断,功能多了,你把合法性判断全部写在main方法中,眼花缭乱,整体性不好。)
    同时,也无需多写,这个方法该干嘛就只写实现这个功能的代码,不该它做的事情就不写进去. 比如只是查找下标就不用吧打印也写进去,具体查找到下标后的下一步就交给这个方法以外的其他代码来实现
    eg:
    package com.qfedu.a.homework;

public class HomeWork4 {
public static void main(String[] args) {
int[] array = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};

	boolean ret = remove(array, 5);
	
	if (ret) {
		for (int i = 0; i < array.length; i++) {
			System.out.print(array[i] + " ");
		}
		System.out.println();
	} else {
		System.out.println("方法运行失败!!!");
	}
}

/**
 * 删除数组中指定下标位置的元素
 * 
 * @param arr 需要进行参数操作的数组
 * @param index 指定删除的下标位置
 * @return 方法运行成功返回true,否则返回false
 */
public static boolean remove(int[] arr, int index) {
	// 参数合法性判断
	if (index < 0 || index > arr.length - 1) {
		System.out.println("Input Parameter is Invalid!");
		
		// 参数不合法,方法运行失败!!!
		return false;
	}
	for (int i = index; i < arr.length - 1; i++) {
		arr[i] = arr[i + 1];
	}
	
	// 最后一个赋值为0,占位符
	arr[arr.length - 1] = 0;
	
	return true;
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值