背景:
在生活中,可能会遇上以下场景
现在需要记录员工的姓名,如果用前面所学的知识完成,那么程序需要声明50个变量来分别记住每位员工的姓名,这样做会显得很麻烦。
在Java中,我们可以使用数组来记住这50名员工的姓名。
一、数组
1、概念
数组是指某一组数据的集合,数组中的每一个数据都被称为元素
数组中可以存放任意类型的元素,但是同一个数组里存放的元素类型必须一致。
语法
数据类型[] 数组名 = new 数据类型[数组的长度]
示例
package Day03;
public class Demo01_arrs {
public static void main(String[] args) {
// 数据类型【表示是一个数组 arrs:数组名】 = new 数据类型【数组的长度】
int[] arrs = new int[5];
}
}
2、数组内存图
int[] x; //声明一个int[] 类型的变量
x = new int[100]; //创建一个长度为100的数组
(相当于在一栋居民楼【内存】中,有许多业主【x】)
第二行代码:
(每户业主【x】在所在楼层是有编号的(内存地址),在使用过程中,编号(内存地址)会赋值给x)
3、初始化和默认值
1)初始化
为数组开辟连续的内存空间,并未每个数组元素赋值
动态初始化:只指定长度,由系统给出初始化值
int[] arr = new int[5]
静态初始化:给出初始化值
数据类型[] 数组名 = new 数据类型[] {元素1,元素2,元素3};
2)默认值
数据类型 | 默认初始化值 |
byte、short、int、long | 0 |
float、double | 0.0 |
char | 一个空字符(空格),即’\u0000’ |
boolean | false |
引用数据类型 | null,表示变量不引用任何对象 |
示例1:int类型
package Day03;
//没有特殊声明,默认值是从0开始
public class Demo02_arrs {
public static void main(String[] args) {
// 创建长度为5的数组
int[] arr1 = new int[5];
// 取第一块的值
int a1 = arr1[0];
System.out.println("arr[0]="+a1);
}
}
示例2:double类型
// doublele类型
double[] arr2 = new double[5];
double d1 = arr2[0];
System.out.println("arr2[0]="+d1);
示例3:char、Boolean、引用数据类型
// char
char[] arr3 = new char[10];
System.out.println(arr3[0]);
// Boolean
boolean[] arr4 = new boolean[10];
System.out.println(arr4[0]);
// 引用数据类型
//String s = "李四";//字符串
// String 引用类型,默认值是null
String[] arr5 = new String[10];
System.out.println(arr5[0]);
示例4:静态初始化
package Day03;
/**
* 初始化数组,并赋值
*/
public class Demo03_arrs {
public static void main(String[] args) {
// 静态初始化
// 默认下标是从0开始
int[] arr = new int[] {1,2,3,4};
// 取第一个位置
int a1 = arr[0];
System.out.println(a1);
}
}
方法2:
package Day03;
/**
* 初始化数组,并赋值
*/
public class Demo03_arrs {
public static void main(String[] args) {
// 静态初始化
// 默认下标是从0开始
int[] arr = new int[] {1,2,3,4};
// 取第一个位置
int a1 = arr[0];
System.out.println(a1);
// 使用数组的属性获取数组大小(长度)
System.out.println("数组的长度:"+arr.length);
// 获取数组的最后一个元素的值
// 数组的长度-1即可
// int a5 = arr[arr.length-1];
// 打印最后一个元素的值
System.out.println("最后一个元素的值:"+arr[arr.length-1]);
}
}
示例3:数组的赋值
package Day03;
public class Demo04_arrs {
public static void main(String[] args) {
int[] arr = new int[5];
// int a0 = arr[0];
// 给数组下标为0的元素赋值为1
arr[0] = 1;
// 给数组最后一个元素赋值为999
arr[arr.length-1]= 999;
System.out.println(arr[0]);
System.out.println(arr[arr.length-1]);
}
}
3)数组越界异常(ArrayIndexOutOfBoundsException)
每个数组的索引都有一个范围,即0~length~1.在访问数组的元素时,索引不能超出这个范围,否则程序会报错。
4)空指针异常(NullPointException)
在使用变量引用的一个数组(对象)时,变量必须指向一个有效的的数组对象,如果该变量的值为null,则意味着没有志向任何数组,此时通过该变量访问数组的元素会出现空指针异常。
public class Demo10 {
public static void main(String[] args) {
int[] arr = new int[3];
arr[0] = 10;//0
arr[1] = 20;//1
arr[2] = 30;//2
System.out.println(arr.length);
arr = null;//将arr的引用置空
System.out.println(arr.length);
//String类型的也会为空
//String s = null;
//System.out.println(s.equals("a"));
}
}
5)数组常见操作
使用for循环遍历数组
package Day03;
public class Demo05_arrs {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
for (int i = 0;i < arr.length;i++){
System.out.println(arr[i]);
}
}
}
数组取最值
package Day03;
public class Demo07_arrs {
public static void main(String[] args) {
int[] arr = { 4, 6, 9, 8 }; // 定义一个数组
int max = arr[0]; // 定义变量max用于记住最大数,并假设第一个元素为最大值
// 下面通过一个for循环遍历数组中的元素
for (int x = 1; x < arr.length; x++) {
if (arr[x] > max) { // 比较 arr[x]的值是否大于max
max = arr[x]; // 条件成立,将arr[x]的值赋给max
}
}
System.out.println("max=" + max); // 打印最大值
}
}
上述代码中,定义了一个临时变量max,用于记住数组的最大值。通过for循环获取数组中的最大值,赋值给max变量。
- 思路步骤:
- 首先假设数组中第一个元素arr[0]为最大值
- 后使用for循环对数组进行遍历并比较比max值还大的元素,并赋值给max,此时max就能够在循环结束时记住数组中的最大值。
注意:在for循环中的变量i是从1开始的,原因是程序已经假设第一个元素为最大值
6)数组排序
扩展知识
http://www.jianshu.com/p/8c915179fd02
冒泡排序
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后元素应该回事最大的数。(除了最后一个)
package Day03;
public class Demo08_arrs {
public static void main(String[] args) {
int[] numbers = new int[]{5,7,3,8,5,11};
int temp = 0;
int size = numbers.length;
for (int i = 0;i < size -1; i++){
for (int j = 0;j < size - 1; j++){
if (numbers[j] > numbers[j + 1]){
temp = numbers[j];
numbers[j] = numbers[j + 1];
numbers[j + 1] = temp;
}
}
}
// 打印排序结果
for (int i = 0;i < numbers.length;i++){
System.out.println(numbers[i] + " ");
}
}
}
二、二维数组
多维数组可以简单地理解为数组中嵌套数组,常见的就是二维数组
1、二维数组定义一
// 定义
int[][] arr = new int[3][4];
即定义:3*4的额二维数组。二维数组的长度为3,二维数组中的每一个元素又是一个长度为4的数组。
示例
package Day03;
public class Demo09_arr {
public static void main(String[] args) {
int[][] arr = new int[3][4];
// 二维数组
System.out.println(arr);
// 二维数组中的第一个一维数组,打印的额是内存地址
System.out.println(arr[0]);
// 二维数组中的第一个一维数组的第一个元素
System.out.println(arr[0][0]);
}
}
(因为没有给定初始值,所以获取到的是0.
2、二维数组定义方式二
定义方式2
int[][] arr = new int[3][];
数组中每个元素的长度不确定并灭有赋初始值,取到的是null
赋值后取到的是数组的内存地址
package Day03;
public class Demo10_arr {
public static void main(String[] args) {
// 这是一个二维数组,这个二维数组中有三个一维数组,三个一维数组都没有被赋值
int[][] arr = new int[3][];
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println("-----------------");
// 第一个一维数组中可以存储三个int值
arr[0] = new int[3];
// 第二个一维数组中可以存储五个int值
arr[1] = new int[5];
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
}
}
3、二维数组定义方式三
int[][] arr = {{1,2},{3,4,5,6},{7,8,9}};
二维数组上定义了三个元素,这三个元素都是数组:{1,2},{3,4,5,6},{7,8,9}
示例:
package Day03;
public class Demo02_arr {
public static void main(String[] args) {
// 这是一个二维数组,这个二维数组中每个大括号都代表一个一维数组
int[][] arr = {{1,2,3},{4,5},{6,7,8,9}};
// 二维数组的地址值
System.out.println(arr);
// 一维数组的地址值
System.out.println(arr[0]);
// 1,一维数组中的元素值
System.out.println(arr[0][0]);
}
}
4、二维数组赋值
(多维数组赋值方式和一维数组相似)
package Day03;
public class Demo03_arr {
public static void main(String[] args) {
int[][] arr = new int[3][4];
// arr[0] 是一个数组
arr[0][0] = 10;
arr[2][1] = 100;
System.out.println("arr[0][0]:"+arr[0][0]);
System.out.println("arr[2][1]:"+arr[2][1]);
}
}
5、二维数组遍历
package Day03;
public class Demo04_arr {
public static void main(String[] args) {
// 声明数组
int[][] arr = {{ 1, 2, 3 }, { 4, 5 }, { 6, 7, 8, 9 }};
// 获取到每个二维数组中的一位数组
for (int i = 0;i < arr.length; i++){
// 获取每个一维数组中的元素
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
6、统计二维数组中所有数据的和
方式一:
package Day03;
public class Demo05_arr {
public static void main(String[] args) {
int[][] arr = {{ 22, 66, 44 }, { 77, 33, 88 }, { 25, 45, 65 }, { 11, 66, 99 }};
// 定义变量,记录每次相加的结果
int sum = 0;
// 获取每一个一维数组
for (int i = 0; i < arr.length ; i++) {
for (int j = 0; j < arr[i].length; j++) {
// 累加
sum = sum + arr[i][j];
}
}
System.out.println(sum);
}
}
方法二:
package Day03;
public class Demo06_arr {
public static void main(String[] args) {
int[][] arr = new int[3][];
arr[0] = new int[] {11,12};
arr[1] = new int[] {21,22,23};
arr[2] = new int[]{31,32,33,34};
int sum = 0;
for (int i = 0; i < arr.length; i++) {
int groupSum = 0;
for (int j = 0; j < arr[i].length; j++) {
groupSum = groupSum + arr[i][j];
}
sum = sum + groupSum;
System.out.println("第" + (i + 1) + "个数组和为:" + groupSum);
}
System.out.println("和为: " + sum);
}
}
7、String类的equals()方法
package Day03;
public class Demo07_arr {
public static void main(String[] args) {
int a1 = 10;
int a2 = 20;
// 判断整形是否相等
System.out.println(a1 == a2);
String s1 = "李四1";
String s2 = "李四";
// 判断s1是否和s2相等
// 使用equals 判断字符串【内容】是否相等
System.out.println(s1.equals(s2));
}
}
8、debug模式
debug模式查看代码
调试代码:可以查看代码的执行状况
在需要断电的行数上进行点击(打断点)
右键--》debug模式运行
运行后F8运行下一行。
四、方法
完成特定功能的代码块
1、方法的语法格式
声明一个方法的具体语法格式
修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2,......){
执行语句(方法体)
..........
return 返回值
}
方法格式解释
修饰符:目前:public static
返回值类型:用于限定返回值的数据类型
方法名一个名称:为了方便我们调用方法
参数类型:限定调用方法时传入参数的数据类型
参数名:是一个变量,接受调用方法时传入的参数
方法体:完成功能的代码
return:结束方法以及返回方法指定类型的值,返回结果给调用者。
方法中的“参数类型 参数名1,参数类型 参数名2”被称作参数列表,它用于描述方法在被调用时需要接收的参数,如果方法不需要接收任何参数,则参数列表为空,即()内不写任何内容。方法的返回值必须为方法声明的返回值类型,如果方法中没有返回值,返回值类型要声明为void,此时,方法中return语句可以省略
2、方法注意事项
不调用不会执行
方法和方法的关系是平级关系,不能嵌套但是可以互相调用
方法定义的时候不能再传递数据类型
方法定义的时候参数之间用逗号隔开
如果方法有明确的放回值,一定要有return带回一个值
示例1
编写简单方法,打印一句话
package Day03;
public class Demo01_way {
public static void main(String[] args) {
// 调用方法
print();
}
// 打印字符串【hello method】的方法
public static void print(){
System.out.println("hello method");
}
}
定义了一个print()方法用于打印Hello Method,在main()方法中通过调用print()方法,打印Hello Method。
静态只能调用静态
示例2
求矩形面积方法
package Day03;
public class Demo02_way {
public static void main(String[] args) {
// 调用getArea
int area = getArea(3, 5);
System.out.println("The area is" + area);
}
// 求矩形面积的方法,接收两个参数,其中x为高,y为宽
public static int getArea(int x,int y){
// 使用变量temp记住运算结果
int temp = x * y;
// 将变量temp的值返回
return temp;
}
}
package Day03;
public class Demo03_way {
public static void main(String[] args) {
// 在main方法中获取到计算后的面积
int area = getArea(10, 10);
System.out.println("面积是:" +area);
}
// 定义个方法
public static int getArea(int x, int y){
// 计算面积
int area = x * y;
// 因为定义了返回值的类型(int),必须使用return进行返回
return area;
}
}
执行流程:getArea()-return area-int area-sout
分析:
定义一个getArea()方法用于求矩形的面积
参数x和y分别用于接收调用方法时传入的高和宽
return语句用于返回计算所得的面积
在main()方法中通过调用getArea()方法,获得矩形的面积,并将结果打印
示例3
相互调用
package Day03;
//演示方法互相调用
public class Demo05_way {
public static void main(String[] args) {
}
public static int print1(){
System.out.println("heihei");
// 在方法一中调用方法二
print2();
return 1;
}
public static void print2(){
System.out.println("yeye");
// 同样的在方法二中调用方法一
print1();
return;
}
}
示例4
计算和,返回计算的结果
package Day03;
public class Demo06_way {
public static void main(String[] args) {
int sum = sum1(1,2);
System.out.println("和是: " + sum);
}
public static int sum1(int a, int b){
int sum = (a + b);
// System.out.println("和是: " + sum);
return sum;
}
}
示例5
使用方法打印正方形(动态宽高)
package Day03;
//使用方法打印正方形(动态宽高)
public static void printSquare(int width,int heigh){
// 外循环决定的是行数
for (int i = 0; i < width; i++) {
// 内循环决定的是列数
for (int j = 0; j < heigh; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
3、参数传递(形参和实参)
参数传递:需要调用一个方法时,会把指定的数值,传递给方法中参数,这样方法中的参数就拥有了这个指定的值,在方法中就可以使用该值进行对应的运算。
ctrl l+v接收参数
package Day03;
//求连个数和的方法
//使用sum方法
//数字实参
public class Demo04_way {
public static void main(String[] args) {
int sum = sum(10,20);
System.out.println("和为:"+ sum);
}
// int a,int b形参
public static int sum(int a, int b){
int sum = a + b;
return sum;
}
}
4、方法重载
1)方法重载概述
在同一个类中,存在一个以上同名的方法,只要它们的参数个数或参数类型(形参列表)不同即可。
特点
与返回值类型无关,只看方法名和参数列表
package Day03;
public class Demo08_way {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 30;
int d = 40;
sum(a,b);
sum(a,b,c);
sum(a,b,c,d);
// 调用不同参数类型的重载方法
sum(15.5,15.5);
}
// 定义方法:计算两个参数和
public static void sum(int a,int b){
int sum = (a + b);
System.out.println("和是:" + sum);
}
// 计算三个参数和
public static void sum(int a,int b,int c){
int sum = (a + b +c);
System.out.println("和是:" + sum);
}
// 计算四个参数和
public static void sum(int a,int b,int c,int d){
int sum = (a + b + c + d);
System.out.println("和是:" + sum);
}
// 方法参数类型不同,也成为重载
public static void sum(double a,double b){
double sum = (a + b);
System.out.println("和是:" + sum);
}
}
2)可变参数方法
Java版本中提供了变长参数(varargs),也就是在方法定义中可以使用个数不确定的参数,对于同一方法可以使用不同个数的参数调用,比如sum(a,b),sum(a,b,c),sum(a,b,c,d)。
在具有可变长参数的方法中可以把参数当成数组使用,例如可以循环输出所有的参数值
示例1:
package Day03;
public class Demo09_way {
// main方法
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 30;
int e = 40;
sum(a,b);
sum(a,b,c);
sum(a,b,c,d);
}
// 可以定义任意参数长度的方法
public static void sum(int... a){
// a 可以当做是一个数组来使用
int sum = 1;
for (int i = 0; i < a.length; i++) {
sum += a[i];
}
System.out.println("和是:" +sum);
}
}
3)随机点名器案例
分析:
存储全班同学名字
打印全班同学每一个人的名字
在班级总人数范围内,随机产生一个随机数,查找该随机数所对应的同学名字
技术点:
存储所有同学姓名,String类型的数组
Random类来实现随机数,随机数的大小:【数组变量名.length】
示例1:固定名字
package Day03;
import java.util.Random;
public class Demo10_way {
public static void main(String[] args) {
String[] names = new String[5];
names[0] = "李四";
names[1] = "赵六";
names[2] = "田七";
names[3] = "王五";
names[4] = "老王";
Random r = new Random();
int number = r.nextInt(names.length);
System.out.println("名字是:" + names[number]);
}
}
示例2:用户输入名字
使用Scanner处理用户输入的数据,并存储到数组中
使用do...while循环来实现用户继续点名功能
package Day03;
import java.util.Random;
import java.util.Scanner;
public class Demo11_way {
public static void main(String[] args) {
// 存储学生姓名
String[] names = new String[3];
Scanner sc = new Scanner(System.in);
// 使用循环录入学生姓名
for (int i = 0; i < names.length; i++) {
System.out.println("请输入第" + (i+1) + "个同学的名字");
// 接收键盘录入
String name = sc.next();
// 给数组指定位置赋值
names[i] = name;
}
// 记录是否继续
String isExist;
do {
Random r = new Random();
int number = r.nextInt(names.length);
System.out.println("名字是:" + names[number]);
System.out.println("是否继续随机(yes 继续/任意字符串退出)");
isExist = sc.next();
// equals判断字符串是否相等
}while(isExist.equals("yes"));
System.out.println("感谢使用");
}
}
五、库存管理案例
每个公司需要实现仓库管理系统,需要一下功能:
1、打印库存清单功能
2、库存商品数量修改功能
3、退出程序功能
1、实例:
管理员能够进行的操作(查看、修改、退出)
库存管理:
1)、查看库存清单
2)、修改商品库存数量
3)、退出
请输入要执行的操作序号:
选择 "1.查看库存清单" 功能,则控制台打印库存清单
选择 "2.修改商品库存数量" 功能,需要判断是否登录,登录后才能对,对每种商品库存数进行更新
选择 "3.退出" 功能,则退出库存管理,程序结束
package Day03;
import java.util.Scanner;
public class example {
public static void main(String[] args) {
mainControl();
}
public static int printMenu(){
System.out.println("-------------库存管理------------------");
System.out.println("1.查看库存清单");
System.out.println("2.修改商品库存数量");
System.out.println("3.退出");
return new Scanner(System.in).nextInt();
}
// 主要控制方法
public static void mainControl(){
String name[] = {"联想","苹果"};
double size[] = {15.0,15.6};
double price[] = {6999.99, 12800.0};
int count[] = {0,0};
while (true){
switch (printMenu()){
case 1:
printOrder(name, size, price, count);
break;
case 2:
updata(name, count);
break;
case 3:
System.out.println("谢谢您的使用!");
return;
default:
System.out.println("输入有误请重新输入!");
}
}
}
// 查看库存清单
public static void printOrder(String name[], double size[], double price[],
int count[]) {
int sum = 0, money = 0;
System.out.println("-----------------商品清单-----------------");
System.out.println("品名 尺寸/寸 价格/元 库存/台");
for (int i = 0; i < count.length; i++) {
System.out.println(name[i] + " " + size[i] + " " + price[i]
+ "\t " + count[i] + " ");
sum += count[i];
money += count[i] * price[i];
}
System.out.println("库存总量为:" + sum + "台");
System.out.println("库存总价为:" + money + "元");
}
//修改库存以及登录方法
public static void updata(String name[], int count[]) {
System.out.println("请输入管理员账号:");
String username = new Scanner(System.in).next();
System.out.println("请输入管理员密码:");
String password = new Scanner(System.in).next();
if (login(username, password)) {
for (int i = 0; i < count.length; i++) {
System.out.println("商品" + name[i] + "的库存修改为:");
count[i] = new Scanner(System.in).nextInt();
System.out.println("修改成功!");
}
} else {
System.out.println("用户名或者密码输入错误请重新输入");
return;
}
}
//登录
public static boolean login(String username, String password) {
boolean flag = false;
if (username.equals("admin") && password.equals("admin")) {
flag = true;
} else {
flag = false;
}
return flag;
}
}