Java数组详解:定义、操作、排序、查找、二维数组与Arrays工具类。

数组的概念和特点

什么是数组?

数组就是一个能够存放多个相同数据类型的数据的容器

数组的创建

动态创建

1
2
数据类型[] 数组名 = new 数据类型[数组长度];
数据类型 数组名[] = new 数据类型[数组长度];

代码演示

1
2
3
4
5
6
7
8
9
10
11
12
13
package unit1;

public class Demo1Array {
public static void main(String[] args) {
// 创建一个容量为3的int类型的数组
int[] arr1 = new int[3];
double [] arr2 = new double[5];
String[] arr3 = new String[2];
// 创建一个数组,这个数组不能存数据(容量为0)
long[] arr4 = new long[0];
}
}

静态创建

1
2
数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3};
数据类型[] 数组名 = {元素1, 元素2, 元素3};

代码演示

1
2
3
4
5
6
7
8
9
10
package unit1;

public class Demo2Array {
public static void main(String[] args) {
// 创建一个int数组,数组中有5个元素,数组长度也是5
int[] arr1 = new int[]{1,2,3,4,5};
String[] arr2 = {"Java", "C++", "PHP"};
}
}

注意

  1. 数组的数据类型可以是任意数据类型,包括基本数据类型和引用数据类型
  2. 数组中存放元素的类型,必须是创建数组时指定的类型,不允许出现不同的类型
  3. 创建一个数组时,必须指定数组长度,数组创建成功后,长度就不可以进行改变了。

数组基本操作

数组中的元素,我们可以通过索引(下标)来访问,索引从0开始,到数组长度-1,也就是说一个长度为n的数组,它的索引范围是[0, n-1]。如果超出这个范围,会抛出 ArrayIndexOutOfBoundsException(数组索引越界异常)

语法

1
2
3
4
// 取值
数据类型 变量名 = 数组名[索引];
// 赋值
数组名[索引] = 值;

数组的取值赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package unit1;

public class Demo3Array {
public static void main(String[] args) {
int[] arr = new int[5];
arr[0] = 10;
arr[1] = 11;
arr[2] = 12;
arr[4] = 14;
// 长度为5的数组索引最多只能到4,如果操作的索引超出了
// 会抛出ArrayIndexOutOfBoundsException
// 并且程序会立即终止
// arr[5] = 15;
int num1 = arr[0];
int num2 = arr[2];
System.out.println(num1);
System.out.println(num2);
System.out.println(arr[1]);
System.out.println(arr[4]);
// 获取数组的长度
System.out.println(arr.length);
}
}

数组的循环遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package unit1;

public class Demo4ArrayIter {
public static void main(String[] args) {
int[] arr = new int[]{3,2,4,56,67,2,3,13,2};
for (int i = 0; i < arr.length; i++) {
System.out.println("第"+ (i+1)+"个元素的值为:" + arr[i]);
}
// 数组的顺序遍历
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
// 数组的逆序遍历
for (int i = arr.length - 1; i >= 0; i--) {

}
}
}

通过索引操作数组原理

数组的创建成功后,会在内存中开辟一块区间用来存放这个数组,这个区间是连续的。

当数组存储到内存中后,虚拟机会记住第0个元素的地址,也叫作数组的首地址,后面每一个元素的地址都可以通过计算得来

计算公式:数组首地址+存放数据的字节数*索引位置

随堂练习

  1. 逆序输出一个数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package unit1;

    public class Demo5Array {
    public static void main(String[] args) {
    String[] arr = {"Java", "C++", "PHP", "Python"};
    for (int i = arr.length - 1; i >= 0; i--) {
    System.out.println(arr[i]);
    }
    }
    }

  2. 获取n个学生的成绩,然后保存在数组中,最后计算学生的总分和平均分。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    package unit1;

    import java.util.Scanner;

    /**
    * 获取n个学生的成绩,然后保存在数组中,最后计算学生的总分和平均分。
    */
    public class Demo6Array {
    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入学生个数:");
    int stuCount = sc.nextInt();
    double[] scores = new double[stuCount];
    for (int i = 0; i < scores.length; i++) {
    System.out.print("请输入第" + (i+1)+"名学生的成绩:");
    double score = sc.nextDouble();
    scores[i] = score;
    }
    System.out.println("学生成绩录入完毕......");
    double sum = 0;
    for (int i = 0; i < scores.length; i++) {
    sum += scores[i];
    }
    System.out.println("学生总分为:" + sum);
    System.out.println("平均分为:" + (sum / stuCount));
    }
    }

  3. 求一个n*n矩阵的对角线数字之和

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    package unit1;

    import java.util.Scanner;

    /**
    * 求一个n*n矩阵的对角线数字之和
    * 确定问题:n*n矩阵数组长度为:n*n
    * 4*4 5*5
    */
    public class Demo7Array {
    public static void main(String[] args) {
    int[] arr = {
    1,2,3,4,5, // 0, 1, 2, 3, 4
    2,3,4,5,3, // 5, 6, 7, 8, 9
    7,8,9,0,2, // 10,11,12,13,14
    7,6,5,4,5, // 15,16,17,18,19
    1,2,3,4,5 // 20,21,22,23,24
    };
    int leftNum = 0;
    int rightNum = 0;
    int layer = 5;
    for (int i = 0; i < layer; i++) {
    for (int j = 0; j < layer; j++) {
    int currentIndex = i*layer+j;
    int leftIndex = i*layer+i;
    if(currentIndex == leftIndex) {
    leftNum += arr[leftIndex];
    }
    int rightIndex = (i+1)*(layer-1);
    if(currentIndex == rightIndex) {
    rightNum+=arr[rightIndex];
    }
    }
    }
    System.out.println("左对角求和为:" + leftNum);
    System.out.println("右对角求和为:" + rightNum);
    }
    }

数组的默认初始化

数组一旦经过分配空间,那么数组中每一个位置都会默认有一个值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package unit1;

import java.util.Arrays;

public class Demo8Array {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(Arrays.toString(arr));
double[] arr2 = new double[3];
System.out.println(Arrays.toString(arr2));
char[] arr3 = new char[3];
System.out.println(Arrays.toString(arr3));
boolean[] arr4 = new boolean[3];
System.out.println(Arrays.toString(arr4));
String[] arr5 = new String[3];
System.out.println(Arrays.toString(arr5));
}
}

  • byte、short、int、long的默认值是0
  • float、double的默认值是0.0
  • char的默认值是 ‘\u0000’
  • boolean默认值是 false
  • 引用类型默认值是 null(代表空对象)

Java中的堆和栈

编写一个方法,该方法用于交换两个数的值
方法内交换成功了,但出了方法之后却又失败了,这是为什么?
编写一个方法,该方法用于交换数组两个位置的值
同样是交换,数组的交换却成功了,这是为什么?

Java是基于堆栈的虚拟机,堆、栈是两种数据结构,用来存储数据

栈内存:用来存储局部变量,先进后出、后进先出,内存空间连续,虚拟机会为每一个线程创建一个栈,每一个方法执行时都会创建一个栈帧,该方法内声明的变量会存储到这个栈帧中。

堆内存:用来存储对象和数组,每当创建一个数组或者对象,就会在堆内存中分配存储空间,然后记录下这个对象的首地址。之后,一般会在栈内存中创建一个变量,用来记录它的首地址,这个变量我们一般称之为“引用”

交换两个局部变量,是在swap方法的栈帧中进行交换,swap方法中的num1与num2和main方法中的num1与num2没有任何联系,因此swap中交换成功与main方法没有关系

1.交换两个局部变量

而如果是数组,先在堆内存中分配空间,然后将首地址记录在栈内存中,后续的操作都是根据索引和首地址去堆内存中操作数组。不管是在哪个栈帧中,操作的数组都是同一个数组,因此在swap栈帧中交换数组的值,在main方法中同样能够生效

2.交换数组两个位置的值

数组常见操作

获取数组最值

需求:获取数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72}的最大值,也就是该数组的元素90。

假设法。先假设第0个元素是最大值,遍历数组,将每个元素与假设的最大值进行比较,如果发现遍历到的元素比假设的最大值还要大,就将这个元素假设为最大值。当遍历完毕后,假设的最大值即为真正的最大值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package unit2;

public class Demo1Array {
public static void main(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if(arr[i] > max) {
max = arr[i];
}
}
System.out.println("最大值为:" + max);
}
}

方法封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 获取数组中的最大值
* @param arr 待查找数组
* @return 最大值
*/
public static int getMax(int[] arr) {
int max = arr[0];
if(arr.length == 1) {
return max;
}
for (int i = 1; i < arr.length; i++) {
if(arr[i] > max) {
max = arr[i];
}
}
return max;
}

通过值获取索引

需求:获取元素59在数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72}中的索引。

涉及到查找操作基本都是遍历。

遍历整个数组,拿到每一个元素与待查找元素进行比对,如果相等,就返回当前的索引,如果不同,继续遍历。如果没有找到,就返回-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package unit2;

public class Demo2Array {
public static void main(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
int targetValue = 59;
// 假设找不到,返回-1。之后遍历,如果找到,就修改index的值
// 如果找不到,index就是-1
int index = -1;
for (int i = 0; i < arr.length; i++) {
if(arr[i] == targetValue) {
index = i;
break;
}
}
System.out.println(targetValue + "在数组中的位置为:" + index);
}
}

封装方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 查找指定的值在数组中的索引位置
* @param arr 待查找数组
* @param targetValue 待查找值
* @return targetValue所在的索引,如果值不存在,就返回-1
*/
public static int getIndex(int[] arr, int targetValue) {
for (int i = 0; i < arr.length; i++) {
if(arr[i] == targetValue) {
return i;
}
}
return -1;
}

思考:想要获取最大值所在的索引,如何操作

实现这个操作,假设的就不是最大值了,而是最大值在哪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package unit2;

public class Demo3Array {
public static void main(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
int maxIndex = 0;
for (int i = 1; i < arr.length; i++) {
if(arr[i] > arr[maxIndex]) {
maxIndex = i;
}
}
System.out.println("最大值索引为:" + maxIndex);
}
}

封装方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 获取数组中的最大值所在的索引
* @param arr 待查找数组
* @return 最大值所在的索引位置
*/
public static int getMaxIndex(int[] arr) {
if(arr.length == 1) {
return 0;
}
int max = 0;
for (int i = 1; i < arr.length; i++) {
if(arr[i] > arr[max]) {
max = i;
}
}
return max;
}

数组的反转

需求:将数组反序输出,原数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72},反转后为{72,59,28,45,76,77,18, 90,12,5}。

方式1:先声明一个空的数组,将原数组中的元素一一复制到新的数组中,交叉复制

3.数组反转方法1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package unit2;

import java.util.Arrays;

/**
* 需求:将数组反序输出,原数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72},
* 反转后为{72,59,28,45,76,77,18, 90,12,5}。
*/
public class Demo4Array {
public static void main(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
int[] tmp = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
tmp[arr.length-1-i] = arr[i];
}
System.out.println("反转前:" + Arrays.toString(arr));
System.out.println("反转后:" + Arrays.toString(tmp));
}
}

方式2:将原数组中的元素进行首位对调

4.数组反转方法2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package unit2;

import java.util.Arrays;

/**
* 需求:将数组反序输出,原数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72},
* 反转后为{72,59,28,45,76,77,18, 90,12,5}。
*/
public class Demo4Array {

public static void main(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
for (int i = 0; i < arr.length/2; i++) {
int tmp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = tmp;
}
System.out.println("反转前:" + Arrays.toString(arr));
System.out.println("反转后:" + Arrays.toString(arr));
}

/**
* 方式1
* @param args
*/
public static void main1(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
int[] tmp = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
tmp[arr.length-1-i] = arr[i];
}
System.out.println("反转前:" + Arrays.toString(arr));
System.out.println("反转后:" + Arrays.toString(tmp));
}
}

抽取方法

1
2
3
4
5
6
7
8
9
10
11
/**
* 数组的反转
* @param arr 待反转数组
*/
public static void reverse(int[] arr) {
for (int i = 0; i < arr.length / 2; i++) {
int tmp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = tmp;
}
}

数组元素的删除

需求:删除数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72}索引为2的元素,删除后:{5, 12, 18, 77, 76, 45, 28, 59, 72,0}。

从待删除位置开始,到数组最后一个元素结束,每次循环将当前位置+1的元素赋值给当前位置,最后将最后的元素设置为默认值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package unit2;

import java.util.Arrays;

public class Demo5Array {
public static void main(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
int removeIndex = 2;
for (int i = removeIndex; i < arr.length-1; i++) {
arr[i] = arr[i+1];
}
arr[arr.length-1] = 0;
System.out.println(Arrays.toString(arr));
}
}

抽取方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 删除数组中指定索引位置的元素
* @param arr 待删除数组
* @param removeIndex 待删除位置
* @return 被删除的元素
*/
public static int remove(int[] arr, int removeIndex) {
int item = arr[removeIndex];
for (int i = removeIndex; i < arr.length - 1; i++) {
arr[i] = arr[i+1];
}
arr[arr.length-1] = 0;
return item;
}

数组的插入

需求:在数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72}索引为2的位置插入元素222,插入后:{5, 12, 222, 90, 18, 77, 76, 45, 28, 59, 72}。

插入操作存在数组扩容的操作:创建一个新的数组,新数组长度是原本数组长度+1,之后将所有的元素复制到新数组中,并将新元素插入到指定的位置。从带插入位置往前都是相同位置的拷贝,之后都是+1拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package unit2;

import java.util.Arrays;

public class Demo6Array {
public static void main(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
int[] newArr = new int[arr.length+1];
int value = 111;
int insertIndex = 3;
for (int i = 0; i < insertIndex; i++) {
newArr[i] = arr[i];
}
for (int i = insertIndex; i < arr.length; i++) {
newArr[i + 1] = arr[i];
}
newArr[insertIndex] = value;
System.out.println("原数组:" + Arrays.toString(arr));
System.out.println("新数组:" + Arrays.toString(newArr));
}
}

方法抽取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 插入数组元素
* @param arr 待插入数组
* @param value 待插入值
* @param insertIndex 待插入索引
* @return 插入后新的数组
*/
public static int[] insert(int[] arr, int value, int insertIndex) {
int[] result = new int[arr.length+1];
for (int i = 0; i < insertIndex; i++) {
result[i] = arr[i];
}
for (int i = insertIndex; i < arr.length; i++) {
result[i+1] = arr[i];
}
result[insertIndex] = value;
return result;
}

数组的冒泡排序

冒泡排序就像是水中冒出的气泡一样,从水底到水面由小逐渐变大,最终到达水面就是最大的气泡。冒泡排序则是每一轮都将一个最大值“浮”到最顶端,就像是冒泡一样。

每一轮排序,都将当前元素与相邻的元素比较,如果当前元素大于相邻元素,就交换位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package unit2;

import java.util.Arrays;

public class Demo7Array {
public static void main(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
System.out.println("排序前:" + Arrays.toString(arr));
// 外层循环控制比较轮数,轮数=数组长度-1
for (int i = 0; i < arr.length - 1; i++) {
// 每次执行内层循环时都是一个排序的过程,将最大值找到
for (int j = 0; j < arr.length-1-i; j++) {
if(arr[j] > arr[j+1]) {
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1]=tmp;
}
}
}
System.out.println("排序后:" + Arrays.toString(arr));
}
}

优化方案

只要在排序的过程中确定这个数组已经有序了,那么之后的排序就是不必要的,就可以略过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package unit2;

import java.util.Arrays;

public class Demo7Array {
public static void main(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
System.out.println("排序前:" + Arrays.toString(arr));
// 外层循环控制比较轮数,轮数=数组长度-1
for (int i = 0; i < arr.length - 1; i++) {
// 每一轮排序都假设这个数组已经是有序的
boolean flag = true;
// 每次执行内层循环时都是一个排序的过程,将最大值找到
for (int j = 0; j < arr.length-1-i; j++) {
if(arr[j] > arr[j+1]) {
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1]=tmp;
// 只要发生了交换,就说明目前数组是无序的,需要进行排序
flag = false;
}
}
// 每一轮排序操作完毕后,如果没有发生任何交换,说明数组已经有序了
// 后续的排序就可以跳过了
if(flag) {
break;
}
}
System.out.println("排序后:" + Arrays.toString(arr));
}
}

方法抽取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 数组的冒泡排序
* 将数组元素从小到大排序
* @param arr 待排序数组
*/
public static void bubbleSort(int[] arr) {
// 外层循环控制比较轮数,轮数=数组长度-1
for (int i = 0; i < arr.length - 1; i++) {
// 每一轮排序都假设这个数组已经是有序的
boolean flag = true;
// 每次执行内层循环时都是一个排序的过程,将最大值找到
for (int j = 0; j < arr.length-1-i; j++) {
if(arr[j] > arr[j+1]) {
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1]=tmp;
// 只要发生了交换,就说明目前数组是无序的,需要进行排序
flag = false;
}
}
// 每一轮排序操作完毕后,如果没有发生任何交换,说明数组已经有序了
// 后续的排序就可以跳过了
if(flag) {
break;
}
}
}

数组的选择排序

选择排序是先固定一个位置,然后遍历数组,将最大或者最小的数字放到这个位置,下一轮同理。

其实每一轮都是在现有的小数组上找最值的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package unit2;

import util.ArrayUtil;

import java.util.Arrays;

public class Demo8Array {
public static void main(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
System.out.println("排序前:" + Arrays.toString(arr));
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i+1; j < arr.length; j++) {
if(arr[i] < arr[j]) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}

System.out.println("排序后:" + Arrays.toString(arr));
}
}

抽取方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 数组的选择排序
* 从大到小排序
* @param arr 待排序数组
*/
public static void selectSort(int[] arr) {
for (int i = 0; i < arr.length-1; i++) {
for (int j = i+1; j < arr.length; j++) {
if(arr[i] < arr[j]) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}

二分查找

二分查找也叫作折半查找,要求数组有序,每次查询都是从当前数组的中间位置查询,如果待查询数字比中间的值要大,就从右边的小数组继续查询,如果小,就从左边的小数组继续查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package unit2;

public class Demo9Array {
public static void main(String[] args) {
int[] arr = {5, 12, 18, 28, 45, 59, 72, 76, 77, 90};
int searchValue = 40;
// 中间索引每次循环都要重新计算,计算后本轮使用
// 最大索引和最小索引每次循环都可能发生改变,计算后下一轮使用
int min = 0;
int max = arr.length-1;
while (true) {
// 计算中间索引
int mid = (min + max) / 2;
// 待查找值大于中间值,待查找值在右边
if(searchValue > arr[mid]) {
min = mid + 1;
}else if(searchValue < arr[mid]) {
max = mid - 1;
}else {
System.out.println("成功查找到索引位置为:" + mid);
break;
}
if(max < min) {
System.out.println("带查找数值不存在");
break;
}
}
}
}

方法抽取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* 查找value在数组中的索引位置
* 如果查不到,返回-1
* @param arr 待查找数组
* @param value 待查找值
* @return 所在的索引,如果值不存在,返回-1
*/
public static int binarySearch(int[] arr, int value) {
int min = 0;
int max = arr.length-1;
while (true) {
// 计算中间索引
int mid = (min + max) / 2;
// 待查找值大于中间值,待查找值在右边
if(value > arr[mid]) {
min = mid + 1;
}else if(value < arr[mid]) {
max = mid - 1;
}else {
return mid;
}
if(max < min) {
return -1;
}
}
}

for-each循环遍历

for-each循环也叫作增强for循环

1
2
3
for(数据类型 变量名 : 数组或集合) {

}

等价于

1
2
3
for(int i = 0; i < 数组.length; i++) {
数据类型 变量名 = 数组[i];
}

for-each循环简化了for循环的语法结构,但是无法获取到数组的索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package unit2;

public class Demo10Array {
public static void main(String[] args) {
int[] arr = {5, 12, 18, 28, 45, 59, 72, 76, 77, 90};
for (int i = 0; i < arr.length; i++) {
int value = arr[i];
if(value % 2 == 0) {
System.out.print(value + " ");
}
}
System.out.println();
for(int value : arr) {
if(value % 2 == 0) {
System.out.print(value + " ");
}
}
}
}

方法中的可变参数

某些情况下,方法中的参数可能不确定,比如需求是“编写一个方法,这个方法用来计算数字之和”,此时可以使用可变参数

1
2
3
修饰符 返回值类型 方法名(数据类型... 参数名) {

}

可变参数在使用时可以视为一个数组,传参时也可以传递一个数组,也可以传任意个数的指定数据类型的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package unit2;

public class Demo11Array {
public static void main(String[] args) {
System.out.println(add(1,2));
System.out.println(add(1,2,3,4));
System.out.println(add(1));
System.out.println(add());
}

/**
* 计算任意个数字之和
* @param nums
* @return
*/
public static int add(int... nums) {
int sum = 0;
for (int num : nums) {
sum += num;
}
return sum;
}

}

随堂练习

  1. 现有一个已经排序好的数组,输入一个数,将这个数按照正常的排序插入到数组的特定位置中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    package unit2;

    import util.ArrayUtil;

    import java.util.Arrays;

    /**
    * 现有一个已经排序好的数组,输入一个数
    * 将这个数按照正常的排序插入到数组的特定位置中。
    * 待插入位置:当前位置元素比待插入值小,但下一个元素比待插入值大
    * 先找到待插入位置,再调用insert方法
    * 5
    * 2,4,6,8,10
    */
    public class Demo13Array {
    public static void main(String[] args) {
    int[] arr = {2,4,6,8,10,12};
    int insertValue = 0;
    int insertIndex = -1;
    for (int i = 0; i < arr.length; i++) {
    if(i == 0 && arr[i] >= insertValue) {
    insertIndex = 0;
    break;
    }
    if(i == arr.length-1) {
    insertIndex = i+1;
    break;
    }
    if(arr[i] <= insertValue && arr[i+1] > insertValue) {
    insertIndex = i + 1;
    break;
    }
    }
    int[] newarr = ArrayUtil.insert(arr, insertValue, insertIndex);
    System.out.println("插入后:" + Arrays.toString(newarr));
    }
    }

  2. 定义一个4行4列的矩阵,将这个矩阵四周的数据清零。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    package unit2;

    /**
    * 定义一个4行4列的矩阵,将这个矩阵四周的数据清零。
    * i j i == 0 || i == 3 || j == 0 || j == 3
    *
    * 1 2 3 4 0,0->0 | 0,1->1 | 0,2->2 | 0,3->3
    * 5 6 7 8 1,0->4 | 1,1->5 | 1,2->6 | 1,3->7
    * 7 8 9 0 2,0->8
    * 4 3 2 1
    */
    public class Demo14Array {
    public static void main(String[] args) {
    int[] arr = {
    1, 2, 3, 4,
    5, 6, 7, 8,
    7, 8, 9, 5,
    4, 3, 2, 1
    };
    for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
    int index = i*4+j;
    if(i==0||j==0||i==3||j==3) {
    arr[index] = 0;
    }
    }
    }


    for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
    int index = i*4+j;
    System.out.print(arr[index] + " ");
    }
    System.out.println();
    }
    }
    }

  3. 定义一个数组,将数组中的重复数据去重。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    package unit2;

    import util.ArrayUtil;

    import java.util.Arrays;

    /**
    * 定义一个数组,将数组中的重复数据去重。
    * 参考选择排序,固定一个位置,遍历数组,将后面与当前位置相同的元素全部清除
    * 最终就得到了一个数组
    * 1,2,2,3,3,3,3,4,4,5,6,7,8,8
    */
    public class Demo15Array {
    public static void main(String[] args) {
    int[] arr = {1,2,2,3,3,3,3,4,4,5,6,7,8,8};
    int itemCount = arr.length;
    for (int i = 0; i < itemCount-1; i++) {
    for (int j = i+1; j < itemCount; j++) {
    if(arr[i] == arr[j]) {
    ArrayUtil.remove(arr, j);
    itemCount--;
    j--;
    }
    }
    }
    System.out.println(Arrays.toString(arr));
    }
    }

  4. 给定一个数组,将数组中所有的偶数放到前面,奇数放到后面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    package unit2;

    import java.util.Arrays;

    /**
    * 给定一个数组,将数组中所有的偶数放到前面,奇数放到后面
    * 定义一个新的数组,长度与原数组一致,再定义两个“指针”
    * 分别代表左边操作到的索引位置和右边操作到的索引位置
    * 遍历原数组,遇到了偶数就存到左边,然后左指针+1
    * 遇到了奇数就存到右边,然后右指针-1
    *
    * 这道题与之前不同,以前操作数组就是无脑的遍历
    * 遍历到谁就操作谁。而这题则需要引入外部的指针
    * 每操作一次,指针都会发生变化
    */
    public class Demo16Array {
    public static void main(String[] args) {
    int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
    int[] newArr = new int[arr.length];
    int leftIndex = 0;
    int rightIndex = arr.length-1;
    for (int i = 0; i < arr.length; i++) {
    int value = arr[i];
    if(value % 2 == 0) {
    newArr[leftIndex] = value;
    leftIndex++;
    }else {
    newArr[rightIndex] = value;
    rightIndex--;
    }
    }
    System.out.println("归类后:" + Arrays.toString(newArr));
    }
    }

  5. 将一个数组按照[1,2,3,4]的格式进行输出。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    package unit2;

    /**
    * 将一个数组按照[1,2,3,4]的格式进行输出。
    */
    public class Demo17Array {
    public static void main(String[] args) {
    int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
    System.out.print("[");
    for (int i = 0; i < arr.length; i++) {
    if(i == arr.length-1) {
    System.out.print(arr[i]);
    }else {
    System.out.print(arr[i] + ", ");
    }
    }
    System.out.print("]");
    }
    }

    方法封装

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    /**
    * 将数组转换成字符串
    * @param arr 待转换数组
    * @return 格式为 [元素1, 元素2, 元素3]
    */
    public static String toString(int[] arr) {
    String s = "";
    s += "[";
    for (int i = 0; i < arr.length; i++) {
    if(i == arr.length-1) {
    s += arr[i];
    }else {
    s += arr[i] + ", ";
    }
    }
    s += "]";
    return s;
    }
  6. 现有两个数组,比较两个数组的内容是否相同。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    package unit2;

    /**
    * 现有两个数组,比较两个数组的内容是否相同。
    */
    public class Demo18Array {
    public static void main(String[] args) {
    int[] arr1 = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
    // null不能使用.length调用数组的属性
    int[] arr2 = arr1;
    if(arr1 == arr2) {
    System.out.println(true);
    }else if(arr1 == null || arr2 == null) {
    System.out.println(false);
    }else if(arr1.length != arr2.length) {
    System.out.println(false);
    }else {
    boolean flag = true;
    for (int i = 0; i < arr1.length; i++) {
    if(arr1[i] != arr2[i]) {
    flag = false;
    break;
    }
    }
    System.out.println(flag);
    }
    }
    }

    方法抽取

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    /**
    * 比较两个数组内容是否相同
    * @param arr1 数组1
    * @param arr2 数组2
    * @return 如果相同返回true,如果不同返回false
    */
    public static boolean equals(int[] arr1, int[] arr2) {
    if(arr1 == arr2) {
    return true;
    }else if(arr1 == null || arr2 == null) {
    return false;
    }else if(arr1.length != arr2.length) {
    return false;
    }else {
    for (int i = 0; i < arr1.length; i++) {
    if(arr1[i] != arr2[i]) {
    return false;
    }
    }
    return true;
    }
    }

Arrays工具类

toString方法

该方法用于将数组转换成特定的表示形式

1
2
3
4
5
6
7
8
9
10
11
12
package unit3;

import java.util.Arrays;

public class Demo1Arrays {
public static void main(String[] args) {
int[] arr1 = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
String s = Arrays.toString(arr1);
System.out.println(s);
}
}

equals方法

该方法用于比较两个数组的内容是否相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package unit3;

import java.util.Arrays;

/**
* 现有两个数组,比较两个数组的内容是否相同。
*/
public class Demo2Arrays {
public static void main(String[] args) {
int[] arr1 = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
// null不能使用.length调用数组的属性
int[] arr2 = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
System.out.println(Arrays.equals(arr1, arr2));
}
}

sort方法

sort方法对数组中的数据进行排序(升序),使用的算法是快速排序

1
2
3
4
5
6
7
8
9
10
11
12
13
package unit3;

import java.util.Arrays;

public class Demo3Arrays {
public static void main(String[] args) {
int[] arr1 = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
System.out.println("排序前:" + Arrays.toString(arr1));
Arrays.sort(arr1);
System.out.println("排序后:" + Arrays.toString(arr1));
}
}

binarySearch方法

该方法是对一个数组进行二分查找法搜索,使用前提是数组必须有序(从小到大)

1
2
3
4
5
6
7
8
9
10
11
package unit3;

import java.util.Arrays;

public class Demo4Arrays {
public static void main(String[] args) {
int[] arr = {5, 12, 18, 28, 45, 59, 72, 76, 77, 90};
System.out.println(Arrays.binarySearch(arr, 28));
}
}

fill方法

fill方法用于填充数组

1
2
3
4
5
6
7
8
9
10
11
12
package unit3;

import java.util.Arrays;

public class Demo5Arrays {
public static void main(String[] args) {
int[] arr = new int[5];
Arrays.fill(arr, 80);
System.out.println(Arrays.toString(arr));
}
}

数组拷贝copyOf

从原数组拷贝出一个新的数组

1
2
3
4
5
6
7
8
9
10
11
12
package unit3;

import java.util.Arrays;

public class Demo6Arrays {
public static void main(String[] args) {
int[] arr = {5, 12, 18, 28, 45, 59, 72, 76, 77, 90};
int[] copy = Arrays.copyOf(arr, 12);
System.out.println(Arrays.toString(copy));
}
}

在阅读copyOf方法的源码时,我们发现内部调用了一个特殊的方法,这个方法没有方法体

1
2
3
public static native void arraycopy(Object src,  int  srcPos,
Object dest, int destPos,
int length);

native关键字:代表本地方法,本地方法是使用C/C++实现的,因为java是面向对象的语言,性能相较于C/C++略低,如果想要高性能的操作一些数据,或者想要操作一些硬件,就可以使用native方法。

参数介绍

src:源数组,从哪里开始拷贝

srcPos:从源数组什么索引位置开始拷贝

dest:目标数组,拷贝到哪里

destPos:从目标数组什么位置开始赋值

length:从源数组中复制多长

使用arraycopy往数组中插入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package unit3;

import util.ArrayUtil;

import java.util.Arrays;

public class Demo8Arrays {
public static void main(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
// {5, 12, 90, 0, 18, 77, 76, 45, 28, 59, 72}
int[] newArr = new int[arr.length+1];
int insertIndex = 3;
int insertValue = 10;
System.arraycopy(arr, 0, newArr, 0, 3);
System.arraycopy(arr, insertIndex, newArr, insertIndex+1, arr.length-insertIndex);
newArr[insertIndex] = insertValue;
System.out.println("原数组:" + Arrays.toString(arr));
System.out.println("新数组:" + Arrays.toString(newArr));
}
public static void main1(String[] args) {
int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
int[] newArr = new int[arr.length+1];
int value = 111;
int insertIndex = 3;
for (int i = 0; i < insertIndex; i++) {
newArr[i] = arr[i];
}
for (int i = insertIndex; i < arr.length; i++) {
newArr[i + 1] = arr[i];
}
newArr[insertIndex] = value;
System.out.println("原数组:" + Arrays.toString(arr));
System.out.println("新数组:" + Arrays.toString(newArr));
}
}

二维数组

二维数组是一个内部元素也都是数组的特殊的数组

创建语法1

1
2
// 语法1
数据类型[][] 数组名 = new 数据类型[m][n];

m:代表这个数组有多长

n:二维数组的每个元素也是数组,n定义这每一个数组的长度

创建语法2

1
2
// 语法2
数据类型[] [] 数组名 = new 数据类型[m] [];

创建时数组的长度已经固定了,但是数组中每一个元素作为数组时的长度没有固定

创建语法3

1
数据类型[][] 数组名 = {{元素1, 元素2}, {元素1}, {元素1, 元素2, 元素3}};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package unit4;

import java.util.Arrays;

public class Demo1Array {
public static void main(String[] args) {
int[][] arr = new int[3][2];
System.out.println(Arrays.toString(arr));
int[] [] arr2 = new int[4] [];
arr2[0] = new int[]{1,2,3};
arr2[1] = new int[]{1,2};
arr2[2] = new int[]{1,2,3,4,5};
arr2[3] = new int[]{1};
System.out.println(Arrays.toString(arr2));
int num = arr2[2][3];
System.out.println(num);
int[][] arr3 = {
{1,2,3},
{1},
{1,2,3,45}
};
System.out.println(Arrays.toString(arr3));
}
}

二维数组的遍历很简单,就按照传统数组的方式即可。

二维数组外层是一个数组,正常遍历,每次遍历取出当前元素,这个元素也是个数组,再遍历这个数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package unit4;

import java.util.Arrays;

public class Demo2Array {
public static void main(String[] args) {
int[][] arr = {
{1,2,3},
{1},
{1,2,3,45}
};
for (int i = 0; i < arr.length; i++) {
int[] tmp = arr[i];
for (int j = 0; j < tmp.length; j++) {
System.out.print(tmp[j] + " ");
}
System.out.println();
}
System.out.println("===============");
for (int[] tmp : arr) {
for (int num : tmp) {
System.out.print(num + " ");
}
System.out.println();
}
}
}

随堂练习

  1. 有三个班级,第一个班级3个学生,第二个班级4个学生,第三个班级5个学生。要求通过键盘录入三个班级学生的成绩,并计算每个班级学生的的平均成绩和三个班级学生的总均成绩。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    package unit4;

    import java.util.Scanner;

    /**
    * 有三个班级,第一个班级3个学生,
    * 第二个班级4个学生,第三个班级5个学生。
    * 要求通过键盘录入三个班级学生的成绩,
    * 并计算每个班级学生的的平均成绩和三个班级学生的总均成绩。
    */
    public class Demo3Array {
    public static void main(String[] args) {
    double[][] clazz = new double[3][];
    clazz[0] = new double[2];
    clazz[1] = new double[3];
    clazz[2] = new double[4];
    Scanner sc= new Scanner(System.in);
    for (int i = 0; i < clazz.length; i++) {
    double[] scores = clazz[i];
    for (int j = 0; j < scores.length; j++) {
    System.out.print("请输入第" + (i+1)+"班第" + (j+1)+"名学生的分数:");
    scores[j] = sc.nextDouble();
    }
    }
    // 计算每个班的平均分和总平均分
    double totalSum = 0;
    for (int i = 0; i < clazz.length; i++) {
    double[] scores = clazz[i];
    double sum = 0;
    for (int j = 0; j < scores.length; j++) {
    sum += scores[j];
    }
    totalSum+=sum;
    System.out.println("第" + (i+1)+"班的总成绩为:" + sum+",平均分为:" + (sum / scores.length));
    }
    System.out.println("总分为:" + totalSum+",总平均分为:" + (totalSum/9));
    }
    }

  2. 获取数组最大值和最小值操作:利用Java的Math类的random()方法,编写函数得到0到n之间的随机数,n是参数。并找出产生50个这样的随机数中最大的、最小的数,并统计其中>=60的有多少个。
    提示:使用 int num=(int)(n*Math.random());获取随机数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    package unit4;

    import java.util.Arrays;

    /**
    * 获取数组最大值和最小值操作:利用Java的Math类的random()方法,
    * 编写函数得到0到n之间的随机数,n是参数。
    * 并找出产生50个这样的随机数中最大的、最小的数,并统计其中>=60的有多少个。
    * 提示:使用 int num=(int)(n*Math.random());获取随机数
    */
    public class Demo4Array {
    public static void main(String[] args) {
    int[] arr = new int[50];
    for (int i = 0; i < arr.length; i++) {
    arr[i] = getRandom(100);
    }
    int max = arr[0];
    int min = arr[0];
    int count = 0;
    for (int num : arr) {
    if(num > max) {
    max = num;
    }
    if(num < min) {
    min = num;
    }
    if(num >= 60) {
    count++;
    }
    }
    Arrays.sort(arr);
    System.out.println(Arrays.toString(arr));
    System.out.println("最大值:" + max);
    System.out.println("最小值:" + min);
    System.out.println(">= 60个数:" + count);
    }

    /**
    * 获取0-n之间的随机数,但到不了n
    * @param n
    * @return
    */
    public static int getRandom(int n) {
    return (int) (Math.random() * n);
    }
    }

  3. 输入某年某月某日,判断这一天是这一年的第几天?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    package unit4;

    import java.util.Scanner;

    /**
    * 输入某年某月某日,判断这一天是这一年的第几天?
    * 2022 3 14
    */
    public class Demo5Array {
    public static void main(String[] args) {
    int[] arr = {0, 31, 28, 31, 30, 31, 30, 31,31,30,31,30,31};
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入年:");
    int year = sc.nextInt();
    System.out.println("请输入月:");
    int month = sc.nextInt();
    System.out.println("请输入日:");
    int day = sc.nextInt();
    int sum = 0;
    for (int i = 0; i < month; i++) {
    sum+=arr[i];
    }
    // 如果前面把2月加上了,但今年是闰年,就要补1天
    if(month > 2 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) {
    sum += 1;
    }
    System.out.println(sum + day);
    }
    }

  4. 数组A:1,7,9,11,13,15,17,19;数组b:2,4,6,8,10 。两个数组合并为数组c,按升序排列。 要求:使用Arrays类的方法快速实现。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    package unit4;

    import java.util.Arrays;

    /**
    * 数组A:1,7,9,11,13,15,17,19;
    * 数组b:2,4,6,8,10 。两个数组合并为数组c,按升序排列。
    * 要求:使用Arrays类的方法快速实现。
    */
    public class Demo6Array {
    public static void main(String[] args) {
    int[] arr1 = {1,7,9,11,13,15,17,19};
    int[] arr2 = {2,4,6,8,10};
    int[] newArr = Arrays.copyOf(arr1, arr1.length + arr2.length);
    System.arraycopy(arr2, 0, newArr, arr1.length, arr2.length);
    Arrays.sort(newArr);
    System.out.println(Arrays.toString(newArr));
    }
    }

双色球

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package project;

import java.util.Arrays;
import java.util.Scanner;

/**
* 双色球投注区分为红色球号码区和蓝色球号码区,
* 红色球号码区由1-33共33个号码组成,蓝色球号码区由1-16共16个号码组成。
* 投注时选择6个红球号码和1个蓝球号码组成一注进行单式投注,每注金额2元。
* 一等奖:投注号码与当期开奖号码全部相同(顺序不限,下同),即中奖,奖金为500倍;
* 二等奖:投注号码与当期开奖号码中的6个红色球号码相同,即中奖,奖金为400倍;
* 三等奖:投注号码与当期开奖号码中的任意5个红色球号码和1个蓝色球号码相同,即中奖,奖金为300倍;
* 四等奖:投注号码与当期开奖号码中的任意5个红色球号码相同,或与任意4个红色球号码和1个蓝色球号码相同,即中奖,奖金为200倍;
* 五等奖:投注号码与当期开奖号码中的任意4个红色球号码相同,或与任意3个红色球号码和1个蓝色球号码相同,即中奖,奖金为100倍;
* 六等奖:投注号码与当期开奖号码中的1个蓝色球号码相同,即中奖,奖金为5倍。
*
* 1.选号,将6个红球和1个蓝球存储到数组中(长度为7个数组,最后一个元素存蓝球)
* 2.下注,计算投注金额
* 3.生成中奖号码,Math.random
* 4.比较中了几个红球,几个蓝球
* 5.判断中奖金额
*/
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] nums = getNum();
System.out.println(Arrays.toString(nums));
System.out.print("请输入下注数量(每注2元):");
int count = sc.nextInt();
int money = count * 2;
int[] lucks = getLuck();
int redCount = 0;
int blueCount = 0;
if(nums[6] == lucks[6]) {
blueCount++;
}
for (int i = 0; i < 6; i++) {
int num = nums[i];
for (int j = 0; j < 6; j++) {
int luck = lucks[j];
if(num == luck) {
redCount++;
break;
}
}
}
System.out.println("当期中奖号码:" + Arrays.toString(lucks));
// 判断中几等奖
if(redCount == 6 && blueCount == 1) {
System.out.println("恭喜您中了一等奖,奖金为:" + (money * 500));
}else if(redCount == 6) {
System.out.println("恭喜您中了二等奖,奖金为:" + (money * 400));
}else if(redCount == 5 && blueCount == 1) {
System.out.println("恭喜您中了三等奖,奖金为:" + (money * 300));
}else if(redCount == 5 || (redCount == 4 && blueCount == 1)) {
System.out.println("恭喜您中了四等奖,奖金为:" + (money * 200));
}else if(redCount == 4 || (redCount == 3 && blueCount == 1)) {
System.out.println("恭喜您中了五等奖,奖金为:" + (money * 100));
}else if(blueCount == 1) {
System.out.println("恭喜您中了六等奖,奖金为:" + (money * 5));
}else {
System.out.println("很遗憾,您还差一点点就中大奖了,不再来一单吗");
}
}

/**
* 生成中将号码
* @return 中奖号码,数组长度为7,最后一个是蓝球
*/
public static int[] getLuck() {
// int[] arr = new int[7];
// for (int i = 0; i < 6; i++) {
// int num = (int) (Math.random() * 33 + 1);
// arr[i] = num;
// }
// arr[6] = (int) (Math.random() * 16 + 1);
// return arr;
return new int[]{1,5,10,31,20,15,10};
}

/**
* 选号
* @return 选中的号码,数组长度为7,最后一个是蓝球
*/
public static int[] getNum() {
Scanner sc = new Scanner(System.in);
System.out.println("请选择红球(1-33):");
int[] arr = new int[7];
for (int i = 0; i < 6; i++) {
while (true) {
System.out.print("请输入第"+(i+1)+"个红球:");
int num = sc.nextInt();
if(num < 1 || num > 33) {
System.out.println("您输入的号码不在合法范围");
continue;
}
arr[i] = num;
break;
}
}
while (true) {
System.out.print("请选择蓝球(1-16):");
int num = sc.nextInt();
if(num < 1 || num > 16) {
System.out.println("您输入的号码不在合法范围");
continue;
}
arr[6] = num;
break;
}
return arr;
}

}