文章目录
一、数组概述
数组是一种引用数据类型,在内存中存储示意图如下:
1. 数组是一组数据的集合
2. 数组作为一种引用类型
3. 数组元素的类型可以是基本类型,也可以是引用类型,但同一个数组只能是同一种类型
4. 数组作为对象,数组中的元素作为对象的属性,除此之外数组还包括一个成员属性 length, length 表示数组的长度
5. 数组的长度在数组对象创建后就确定了,就无法再修改了
6. 数组元素是有下标的,下标从 0 开始,也就是第一个元素的下标为 0,依次类推最后一个元素的下标为 n-1,我们可以通过数组的下标来访问数组的元素
二、一维数组的声明和使用
1、数组的声明
一维数组的声明格式有以下两种:
1. 数组元素的类型[] 变量名称
2. 数组元素的类型 变量名称[]
数组元素的类型,可以是 java 中的任意类型,变量名称可以是任意合法的标识符,上面两种 格式较常用的是第一种,例如:
int [] a;
Student[] stu
在一行中也可以声明多个数组,例如: int[] a, b, c
2、数组的创建
数组创建有两种方式
第一种,使用 new 操作符来创建数组,格式为:new 数组元素的数据类型[数组元素的个数]
必须清楚数组为引用数据类型,它在堆内存中分配
1. 基本类型的数组
public class ArrayTest01 {
public static void main(String[] args) {
//声明 int 类型的数组,长度为 5
//数组中的元素必须为 int 类型
int[] data = new int[5];
//对数组中的元素进行赋值,
//如果不赋值默认为该类型的默认值,以上数组默认为 0
data[0] = 1;
data[2] = 2;
//输出数组元素
System.out.println(data[0]);
采用 length 属性可以取得数组的长度
for(int i=0; i<data.length;i++){
System.out.println(data[i]);
}
//会抛出ArrayIndexOutOfBoundsException 异常
//数组下标越界
System.out.println("data[10]=" + data[10]);
//不能成功赋值,数组中的类型必须是一种类型
data[0] = "iiii";
}
}
代码如下(示例):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
2. 引用类型的数组
public class ArrayTest02 {
public static void main(String[] args) {
//声明引用类型的数组
Student[] student = new Student[2];
//出现空指针
//因为引用类型的数组,它采用 null 作为默认的初始化值
student[0].id = 1001;
student[0].name = "张三";
student[1].id = 1002;
student[1].name = "李四";
//修正空指针
student[0] = new student();
student[0].id = 1001;
student[0].name = "张三";
student[1] = new student();
student[1].id = 1002;
student[1].name = "李四";
}
}
class Student{
int id;
String name;
}
第二种,使用数组的初始化语句,格式为:数组元素的类型[] 变量名称 = {数组元素 1, 数组元素 2,…数组元素 n}或数组元素的类型 变量名称[] = {数组元素 1,数组元素 2,… 数组元素 n}
public class ArrayTest04 {
public static void main(String[] args) {
//静态初始化
int[] data = {1, 2, 3, 4, 5};
for (int i=0; i<data.length; i++) {
System.out.println(data[i]);
}
}
三、二维数组的声明和使用
二维数组属于多维数组,那么什么是多维数组呢,当数组元素的类型是数组时就成了多维数组, 二维数组的声明格式如下:
1. 数组元素的数据类型[][] 变量名;
2. 数组元素的数据类型 变量名[][];
其中方括号的个数就是数组的维数,声明二维数组如下:
int [][] data;
在这里介绍三种二维数组的创建方式
1. 采用 new 关键字直接创建
public class ArrayTest05 {
public static void main(String[] args) {
//声明二维数组
int[][] data = new int[2][3];
//对二维数组赋值
data[0][0] = 1;
data[0][1] = 2;
data[0][2] = 3;
data[1][0] = 4;
data[1][1] = 5;
data[1][2] = 6;
//输出二维数组
for(int i=0; i<data.length; i++){
for(int j=0; j<data[i].length; j++){
System.out.println(data[i][j]);
}
}
}
}
2. 从高维开始逐维创建
public class ArrayTest06 {
public static void main(String[] args) {
//从高维开始逐维创建
int[][] data = new int[2][];
data[0] = new int[2];
data[1] = new int[4];
data[0][0] = 1;
data[0][1] = 2;
data[1][0] = 1;
data[1][1] = 2;
data[1][2] = 3;
data[1][3] = 4;
//输出二维数组
for (int i=0; i<data.length; i++) {
for (int j=0; j<data[i].length; j++) {
System.out.println(data[i][j]);
}
}
}
}
3. 采用初始化语句块创建数组对象
public class ArrayTest07 {
public static void main(String[] args) {
//静态初始化
// 多个数组之间用逗号隔开
int[][] data = {{1,2},{1,2,3,4}};
for (int i=0; i<data.length; i++) {
for (int j=0; j<data[i].length; j++) {
System.out.println(data[i][j]);
}
}
}
}
四、数组的排序
1、冒泡排序
public class ArraySortTest01 {
public static void main(String[] args) {
int[] data = {3,1,6,2,5};
for(int i=0; i<data.length; i++){
for(int j=0; j<i;j++){
if(data[j]>data[j+1]){
int temp = data[j];
data[j] = data[j+1];
data[j+1] = temp;
}
}
}
for (int i=0; i<data.length; i++) {
System.out.println(data[i]);
}
}
}
**从上面我们看到了比较了 N-1 次,那么第二遍就为 N-2 次比较了,如此类推,比较次数的公 式如下:
(N-1) + (N-2)+…+1=((N-1)N)/2
所以以上总共比较次数为((5-1)5)/2=10
2、选择排序
选择排序对冒泡排序进行了改进,使交换次数减少,但比较次数仍然没有减少。
假设有 5 个数字 3,1,6,2,5 在一个 int 数组中,要求按从小到大排序输出 采用选择排序,选择排序是这样的,先从左端开始,找到下标为 0 的元素,然后和后面的元素依次比较,如果找到了比下标 0 小的元素,那么再使用此元素,再接着依次比较,直到比较完成所有的元素,最后把最小的和第 0 个位置交换。
public class ArraySortTest02 {
public static void main(String[] args) {
int[] data = {3,1,6,2,5};
for(int i=0; i<data.length; i++){
int min = i;
for(int j=i+1; j<data.length; j++){
if(data[j]<data[min]){
min = j;
}
}
if(min != i){
int temp = data[i];
data[i] = data[min];
data[min] = temp;
}
}
for (int i=0; i<data.length; i++) {
System.out.println(data[i]);
}
}
}
五、数组的搜索
1、二分(折半)查找
查找数组中的元素我们可以遍历数组中的所有元素,这种方式称为线性查找。线性查找适合与 小型数组,大型数组效率太低。如果一个数组已经排好序,那么我们可以采用效率比较高的二分查找或叫折半查找算法。
假设,我们准备采用二分法取得 18 在数组中的位置 第一步,首先取得数组 0~9 的中间元素 中间元素的位置为:(开始下标 0 + 结束下标 9)/2=下标 4 通过下标 4 取得对应的值 15 18 大于 15,那么我们在后半部分查找
第二步,取数组 4~9 的中间元素 4~9 的中间元素=(下标 4 + 1 +下标 9)/2=下标 7 下标 7 的值为 18,查找完毕,将下标 7 返回即可
public class BinarySearchTest01 {
public static void main(String[] args) {
int[] data = {11,12,13,14,15,16,17,18,19,20};
int index = binarySearch(data, 18);
System.out.println(index);
}
//采用折半查找必须建立在排序的基础上
private static int binarySearch(int[] data, int value){
int beginPos = 0;
int endPos = data.length-1;
while(beginPos <= endPos){
int midPos = (beginPos+endPos)/2;
if(value < midPos){
endPos = midPos-1;
}else if(value > midPos){
endPos = midPos+1;
}else{
return midPos;
}
}
return -1;
}
六、Arrays 工具类
1、Arrays.sort 的使用
static void sort(byte[] a)
对指定的 byte 型数组按数字升序进行排序。
import java.util.Arrays;
public class ArraysUtilTest01 {
public static void main(String[] args) {
int[] data = {3,1,6,2,5};
Arrays.sort(data);
for (int i=0; i<data.length; i++) {
System.out.println(data[i]);
}
System.out.println("----------------");
for (int i=data.length-1; i>=0; i--) {
System.out.println(data[i]);
}
}
}
2、Arrays.binarySearch 的使用
static int binarySearch(byte[] a, byte key)
使用二分搜索法来搜索指定的 byte 型数组,以获得指定的值。
import java.util.Arrays;
public class ArraysUtilTest02 {
public static void main(String[] args) {
int[] data = {3,1,6,2,5};
Arrays.sort(data);
for (int i=0; i<data.length; i++) {
System.out.println(data[i]);
}
System.out.println("");
int index = Arrays.binarySearch(data, 3);
System.out.println("index=" + index);
}
}
总结
本章对一维、二维数组进行了学习,了解了数组的声明和使用,并学习了数组的两种排序方法,冒泡排序、选择排序,学习了数组的二分查找,幸运的是这些方法SUN公司已经帮我们写好,封装在Arrays工具类中,我们只需要调用即可,要学会使用jdk帮助文档,忘记的方法在里面查。