数组
数组是一组数据,可以存放多个同一类型的数据;数组本身也一种数据类型,属于引用类型 ;
1、数组的初始化:
1.1动态初始化:
- 语法:
数据类型 数组名[] = new 数据类型[数组大小];//数组的初始元素默认为0
int a[] = new int[5]; //创建一个数组,名字为a,存放5个int数据。
package com.muyu.javase.array;
public class ArrayDemo1 {
public static void main(String[] args) {
int array[] = new int[5]; //初始化数组,在堆中开辟一个容量为5的数组空间
// 打印数组每个值
for (int i = 0; i < 5; i++) {
System.out.print(array[i] +"\t");// 0 0 0 0 0
}
}
}
- 数组的引用;
数组名[下标/索引]
数组的下标是从0开始。
1.2 动态初始化2
- 语法:
1. 声明数组:数据类型 数组名[];
2. 创建数组空间: 数组名 = new 数据类型[数组大小];
package com.muyu.javase.array;
public class ArrayDemo1 {
public static void main(String[] args) {
int array[]; // 声明数组
array = new int[5]; //初始化数组,在堆中开辟一个容量为5的数组空间
// 打印数组每个值
for (int i = 0; i < 5; i++) {
System.out.print(array[i] +"\t");// 0 0 0 0 0
}
}
}
1.3 静态初始化
- 语法
数据类型[] 数组名 = {元素值1,元素值2,...};
当知道数组的具体大小和元素的具体值的时候,就可以使用静态初始化方式。
package com.muyu.javase.array;
public class ArrayDemo2 {
// 求数组的总和与平均值
public static void main(String[] args) {
double[] hens = {2.0, 3.5, 1.8, 3.0, 2.1};
double sum = 0;
double average;
for (int i = 0; i < hens.length; i++) {
sum += hens[i];
}
average = sum/hens.length;
System.out.println("数组的总和为:"+sum+"\t"+"数组的平均值为:"+average);
}
}
2、数组使用注意事项和细节
- 数组是多个相同类型数据的组合;
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但数据类型必须单一,不能混用。
- 数组创建后,如果没有赋值,使用默认值:
int 0; short 0;byte 0; long 0;
float 0.0; double 0.0;
char \u0000;
boolean false;
String null;
- 使用数组的步骤:1)声明数组并开辟空间;2)给数组各个元素赋值;3)使用数组
- 数组的下标是从0开始。
- 数组下标必须在规定范围内使用,否会报下标越界异常。
- 数组属于引用类型,数组型数据时对象(object)
3、数组的赋值机制
基本数据类型的赋值(值传递),就是将这个值复制了一份给变量,变量的值改变不会影响原数值。
package com.muyu.javase.array;
public class AssignDemo1 {
//基本数据类型的赋值
public static void main(String[] args) {
char aph = 'A';
char re_aph = aph;
System.out.println("aph:"+aph+"\tre_aph:"+re_aph);//aph:A re_aph:A
re_aph = 'B';
System.out.println("aph:"+aph+"\tre_aph:"+re_aph);//aph:A re_aph:B,re_aph的改变不影响aph的值
}
}
数组在默认情况是引用传递(地址传递),赋的值是地址。
package com.muyu.javase.array;
public class AssignDemo1 {
//基本数据类型的赋值
public static void main(String[] args) {
//数组类型赋值
int[] array1 = {1,2,3,4};
int[] array2 = array1;
System.out.println("\n====array1====");
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i]+"\t"); //1 2 3 4
}
System.out.println("\n====array2====");
for (int i = 0; i < array2.length; i++) {
System.out.print(array2[i]+"\t"); //1 2 3 4
}
//=======================================================================
System.out.println("\n修改array中元素以后");
array2[1] = 10;
System.out.println("====array1====");
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i]+"\t"); //1 10 3 4
}
System.out.println("\n====array2====");
for (int i = 0; i < array2.length; i++) {
System.out.print(array2[i]+"\t"); //1 10 3 4 //array2与array1指向的是同一个地址
}
}
}
数组的赋值是将堆中开辟的内存地址进行引用
如果两个数组或者多个数组指向的都是同一个地址,那么任何一个数组中的元素改变,都会影响其余的数组。
3.1 数组的拷贝
将数组array1中元素拷贝得到array2中,且两个数组互不影响
package com.muyu.javase.array;
public class CopyArrayDemo {
//将数组array1中元素拷贝得到array2中,且两个数组互不影响
/*
思路:
两个数组互不影响,所以要开辟一个新的空间;
两个数组中的元素是一样的,所以要进行遍历赋值
*/
public static void main(String[] args) {
int[] array1 = {1,2,3,4,5};
//初始化array2,开辟一个新的与array1大小一样的数组空间
int[] array2 = new int[array1.length];
//将array1中元素遍历,并赋值到array2中
for (int i = 0; i < array1.length; i++) {
array2[i] = array1[i];
}
for (int i = 0; i < array2.length; i++) {
System.out.print(array2[i]+"\t");
}
}
}
3.2 数组翻转
package com.muyu.javase.array;
public class FlipArrayDemo {
//翻转数组
/*
思路:
1、将数组第一位与最后一位互换;
2、将数组第二位与倒数第二位互换
3、以此类推
4、翻转次数为array.length/2
5、互换元素的下标关系:i,array.length-i-1
*/
public static void main(String[] args) {
int[] array1 = {1,2,3,4,5};
//数据中转
int temp = -1;
//数组长度
int len = array1.length;
//翻转元素
for (int i = 0; i < len/2; i++) {
temp = array1[i];
array1[i] = array1[len-i-1];
array1[len-i-1] = temp;
}
for (int i = 0; i < len; i++) {
System.out.print(array1[i]+"\t");
}
}
}
3.3数组扩容
package com.muyu.javase.array;
import java.util.Scanner;
public class AddArrayDemo {
//数组扩容
/*
思路:
1、java中数组初始化以后,数组空间的容量已经固定,数组的长度也就固定
2、要将数组扩容,需要新开辟一个更大的数组空间,新数组空间的大小取决于要添加元素的数量和原数组大小。
3、将原数组的元素遍历赋值到新数组中,再将要添加的元素,赋值到新数组中。
4、将原数组指向新数组的空间地址
---------------------------------------------------------------------------------------------
扩展:实现数组动态扩容,添加用户输入的值。
*/
public static void main(String[] args) {
int[] array1 = {1,2,3,4,5};
do {
int len = array1.length;
System.out.println("请输入要添加的元素:");
Scanner input = new Scanner(System.in);
int a = input.nextInt();
//创建新的数组
int[] array2 = new int[len+1];
//将array1中元素赋值到array2中;
for (int i = 0; i < len ; i++) {
array2[i] = array1[i];
}
//将要添加的元素赋值到array2中并放在array1最后一个元素的后面;
array2[len] = a;
//array1指向新的数组空间
array1 = array2;
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i]+"\t");
}
System.out.println("是否继续添加:y/n");
Scanner confirm = new Scanner(System.in);
char key = confirm.next().charAt(0);
if (key == 'n'){
break;
}
}while (true);
}
}
3.4数组缩减
package com.muyu.javase.array;
import java.util.Scanner;
public class ReduceArrayDemo {
//数组缩减
/*
思路:
1、java中数组初始化以后,数组空间的容量已经固定,数组的长度也就固定
2、要将数组缩减,需要新开辟一个更小的数组空间,新数组空间的大小取决于要缩减元素的数量和原数组大小。
3、将原数组的元素遍历赋值到新数组中,如果元素是要删除的元素就跳过,进入下一元素;
4、给array2数组遍历赋值时,需要给array2数组指定下标
5、将原数组指向新数组的空间地址
---------------------------------------------------------------------------------------------
*/
public static void main(String[] args) {
int[] array1 = {1,2,3,4,5};
do {
int len = array1.length;
System.out.println("请输入要删除的数:");
Scanner input = new Scanner(System.in);
int a = input.nextInt();
//开辟新的数组空间
int[] array2 = new int[len-1];
int len2 = array2.length;
//array2数组下标
int index = 0;
//将数组array1中的元素赋值到array2中,如果元素是要删除的元素就跳过,进入下一元素
for (int i = 0; i < len; i++){
if (array1[i]==a){
continue;
}
if (index==len2){
break;
}
array2[index] = array1[i];
index++;
}
//array1指向新的数组空间
array1 = array2;
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i]+"\t");
}
if (array1.length==1){
System.out.println("已经是最后一个元素,不允许删除");
break;
}
//是否继续删除
System.out.println("是否继续删除:y/n");
Scanner confirm = new Scanner(System.in);
char key = confirm.next().charAt(0);
if (key == 'n'){
break;
}
}while (true);
}
}
4、排序和查找
4.1 排序
排序是将多个数据,依据指定的顺序进行排列的过程
排序的分类:
- 内部排序:将需要处理的所有数据都加载到内部存储器中进行排序。(交换排序,选择排序和插入排序)
- 外部排序:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。(合并排序法和直接合法并排序法)
package com.muyu.javase.array;
public class BubbleSortDemo1 {
//冒泡排序
/*
1、第一轮找出数组中最小的数,放在首位;
2、第二轮从最小数的后面数中继续找出最小的数放在首位
3、以此类推
*/
public static void main(String[] args) {
int[] arrary = {24,50,16,40,59,77};
int temp = -1;
for (int i = 0; i < arrary.length; i++) {
for (int j = i+1; j < arrary.length ; j++) {
// 如果前面的数大于后面的数,就将两个数互换
if(arrary[i]>arrary[j]){
temp = arrary[i];
arrary[i] = arrary[j];
arrary[j] = temp;
}
}
}
for (int i = 0; i < arrary.length; i++) {
System.out.print(arrary[i]+"\t");
}
}
}
4.2 搜索
- 顺序查找:从头到尾或者从尾到头的搜索顺序进行查找。
package com.muyu.javase.array;
import java.util.Scanner;
public class SeqSearchDemo {
//顺序搜索
/*
思路:
1、从数组的首位开始遍历;
2、将每个元素与目标元素对比,如果是目标元素就输出目标元素的下标(初始化一个变量记录下标)
3、遍历结束,下标值没变说明没有找到目标元素。
*/
public static void main(String[] args) {
String[] people = {"Java","Python","C++","C","GO","JavaScript"};
do {
Scanner input = new Scanner(System.in);
System.out.println("输入查询的编程语言:");
String key = input.next();
//记录下标
int index = -1;
for (int i = 0; i < people.length; i++) {
//从头开始查询,如果能匹配到,就输出下标
if (people[i].equals(key)){
index = i;
System.out.println(people[i]+"下标为:"+index);
break;
}
}
//如果下标没变过,说明没有查询到
if (index == -1){
System.out.println("未搜索到内容");
}
//是否继续查询
System.out.println("是否继续查询:y/n");
Scanner quit = new Scanner(System.in);
char y_quit = quit.next().charAt(0);
if(y_quit == 'n'){
break;
}
}while (true);
}
}
- 二分查找:当数组是已排序的数组时,可以使用二分查找;
package com.muyu.javase.array;
public class BinarySearchDemo {
//二分查找
/*
思路:
从排序数组的中间开始查找,如果中间值就是目标元素,就直接输出;
如果不是,比较中间值与目标元素的大小;
中间值比目标元素大,说明目标元素在中间元素的左边,对左边区间再进行二分;
中间值比目标元素小,说明目标元素在中间元素的右边,对右边区间再进行二分;
*/
public static void main(String[] args) {
int[] array = {1,3,4,8,9,22,25};
int len = array.length;
int num = 9;
int left = 0;
int right = len-1;
while (left<=right){
//二分
int mid = (left+right)/2;
if (array[mid]==num){
System.out.println("下标:"+mid);
break;
//区间右移
}else if (array[mid] < num){
left = mid + 1;
//区间左移
}else {
right = mid - 1;
}
}
}
}
5、二维数组
5.1 二维数组的定义
二维数组是指一位数组里面的元素也是一个一位数组。
5.2 二维数组的使用
- 动态初始化1。
语法:
数据类型[][] 数组名 = new 数据类型[大小][大小]
package com.muyu.javase.array;
public class TwoDimensionalDemo1 {
//二维数组 int[4][4],第一个[4]表示第一个一维数组的大小(或者说是行)
//第二个[4]表示第一个一维数组中的一维数组的大小(或者说是列)
public static void main(String[] args) {
int[][] twoArray = new int[4][4];//四行四列的二维数组
for (int i = 0; i < twoArray.length; i++) {
for (int j = 0; j < twoArray[0].length; j++) {
System.out.print(twoArray[i][j]+"\t");
}
System.out.println();
/*输出
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
*/
}
}
}
- 动态初始化2
先声明:数据类型[][] 数组名;
再定义:数组名 = new 数据类型[大小][大小]
再赋值:for循环
package com.muyu.javase.array;
public class TwoDimensionalDemo2 {
public static void main(String[] args) {
int[][] twoArray;//先声明
twoArray = new int[4][4];//再开辟数组空间
//赋值
for (int i = 0; i < twoArray.length; i++) {
for (int j = 0; j < twoArray[0].length; j++) {
twoArray[i][j] = j;
}
}
//打印
for (int i = 0; i < twoArray.length; i++) {
for (int j = 0; j < twoArray[0].length; j++) {
System.out.print(twoArray[i][j] + "\t");
}
System.out.println();
}
}
}
- 动态初始化-列数不确定
数据类型[][] 数组名 = new 数据类型[大小][]
package com.muyu.javase.array;
public class TwoDimensionalDemo3 {
//不确定列
public static void main(String[] args) {
int[][] twoArray = new int[4][];
for (int i = 0; i < twoArray.length; i++) {
// 动态为每一列开辟数组空间
twoArray[i] = new int[i+1];
//赋值
for (int j = 0; j < twoArray[i].length; j++) {
twoArray[i][j] = i;
}
}
//输出twoArray
for (int i = 0; i < twoArray.length; i++) {
for (int j = 0; j < twoArray[i].length; j++) {
System.out.print(twoArray[i][j]+"\t");
}
System.out.println();
/*输出
0
1 1
2 2 2
3 3 3 3
*/
}
}
}
- 静态初始化
数据类型[][] 数组名 = {{value1,value2...},{value1,value2...},{value1,value2...}...};
package com.muyu.javase.array;
public class TwoDimensionalDemo4 {
//静态初始化,打印杨辉三角
/*
思路:
1、杨辉三角每行的首位和末尾都是1。
2、中间的数是上一行的前一列数加上后一列数的和
array[i][j] = array[i-1][j-1] + array[i-1][j]
3、每行数值的个数为 行数+1(行数以0计数)
*/
public static void main(String[] args) {
int[][] array = new int[5][];
for (int i = 0; i < array.length; i++) {
//初始化嵌套的一位数组
array[i] = new int[i+1];
for (int j = 0; j < array[i].length; j++) {
if (j==0 || j==array[i].length-1){
array[i][j] = 1;
}else {
array[i][j] = array[i-1][j-1] + array[i-1][j];
}
}
}
//打印
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j]+" ");
}
System.out.println();
}
}
}
5.3 二维数组使用细节和注意事项
- 二维数组的声明方式:
1、 数据类型[][] 数组名;
2、 数据类型[] 数组名[];//不建议使用
3、 数据类型 数组名[][];
- 二维数组实际上是由多个一位数组组成的,他的各个一位数组的长度可以相同,也可以不相同。