Java数组,
Java数组,
数组的作用:是用于存储大量相同类型的数据。
一、语法
1.是一个数据类型。
2.在现有数据类型的后面,加上[]就变成了数组类型。
数据类型->数组类型
int -> int[]
byte -> byte[]
char ->char[]
int[] -> int[][]
int[][] -> int[][][]
1.1初始化数组
1.1.1动态初始化数组
指定数组的长度,不指定数组里面每个元素的实际内容。实际内容全部自动填充默认值,如果是整数则为0,浮点则是0.0,引用类型的则是null,boolean类型则是false。
数据类型[] 变量名 = new 数据类型[长度];
eg.
// 声明一个类型为double[]的变量,名为wages // 使用new关键字创建一个double类型的数组,长度为30(连续30个double) // new以后,需要连续分配30个double类型的内存空间 // 30个double的值,全部都是默认值 double[] wages = newdouble[30]; |
1.1.2静态初始化数组
指定内容,不指定长度。长度系统自动计算。在{}里面直接指定每个元素,元素之间用逗号隔开
数据类型[] 变量名 = new 数据类型[]{};
// 声明一个类型为double[]的变量,名为wages // 内容在内存里面按照代码的顺序依次排列 double[] wages = newdouble[]{1.0, 3, 5, 6.4}; |
1.2使用数组
1.2.1获取数组的长度
变量名.length:返回int类型
1.2.2获取数组里面的某个值(元素)
利用偏移量来进行获取,这个偏移量不需要程序员计算字节,只需要计算偏移多少个元素即可。
偏移量从0开始,0是第一个正整数,也表示第一个元素不需要偏移即可获取。
数组变量[索引]
1.2.3给数组里面的某个元素赋予值
把数组里面的元素,当做是一个变量来使用即可!
数组变量[索引] = 值;
eg.
ar1[7] = 41;
1.2.4使用循环输出数组里面所有的元素的值
数组长度有多少,就循环输出多少次,并且第一个元素从0开始
eg.
for( int i=0; i<arg1.length; i++ ){
System.out.println( arg1[i] );
}
1.2.5数组的排序
把无序的数据,整理变成有序的数据。
冒泡排序
循环一次数组,找到数组里面最大的元素,并且把此元素的移动到数组的最后面。
步骤
1.循环数组,只需要循环长度减一次
2.在循环里面,如果发现左边的数比右边的数大,交换两个数的位置
3.在前面这个循环的外面,嵌套一层循环,循环数组长度减一次
4.修改内层循环的比较次数,减去外层循环的计数器
Arrays.sort 使用JDK自带的排序算法
Arrays.parallelSort Java 8新增的并行排序算法
二、数组存储方式
数组是一种引用数据类型,所有的引用数据类型,必须要new才能得到实际的值。除了char类型的数组外,其他的所有类型的数组都是输出内存地址,而char数组输出的是实际内容。
输出流System.out是PrintStream对象,PrintStream有多个重载的println方法,其中一个就是public void println(char[] x),直接打印字符数组的话,不像int[]等其他数组,它会直接调用这个方法来打印,因而可以打印出数组内容,而不是地址。
// 1.声明一个int[]类型的变量,名为ar1 // 2.创建10个连续的int,放到一个数组里面,并且返回内存地址[I@***,其中[I@表示int数组;[B是Byte数组 //除了char类型的数组外,其他的所有类型的数组都是输出内存地址,而char数组输出的是实际内容 // 3.把返回的内存地址给ar1作为值 // 每个int都是为0 int[] ar1 = newint[10];
System.out.println(ar1); |
系统把内存分为栈、堆两个区域,所有的变量的值,都是存储在栈里面。
基本类型的值,就是变量的值;引用类型的值,只是一个内存地址。
引用类型利用这个内存地址,到堆里面去获取实际的数据。
引用数据类型的值,也被称之为"指针"。
但是Java里面不能直接操作"指针",都系统自动控制的。
指针其实就是一个数字!但是不能被直接当做数字使用。
三、Java数组的特点:
长度不可变,在new的时候,数组的长度是多少,那么会一直是那么长。
3.1变相进行数组扩容
既然Java的数组长度是不能变的,那么就创建一个新的数组,并且把旧的数组里面的内容,复制到新数组里面。
最后把新数组作为使用的数组。
int[] ar = newint[]{10,20,30,40,50};
//把1/2/3步骤全部使用多行注释给注释掉,那么就会出现"数组索引超出边界异常" // java.lang.ArrayIndexOutOfBoundsException
//把容量改为10 //1.创建一个长度为10的新数组 int[] t = newint[10]; //2.把ar里面的每个元素,复制到新数组里面 for( inti = 0; i < ar.length; i++ ) { // 把ar数组里面i位置的值,赋予给t数组里面的i位置 // i是0~4 t[i] = ar[i]; } //3.把新数组赋予给ar变量 ar = t;
//在索引为5、6的位置,分别是(666,777) ar[5] = 666; ar[6] = 777;
System.out.println( ar.length );// 10
for( inti = 0; i < ar.length; i++ ) { // 10 20 30 40 50 666 777 System.out.println( ar[i] ); } |
3.2在数组的中间部分插入、删除元素
如果要在中间插入元素:
1.要把现有的位置的元素移动在后面一位,在移动之前,需要先检查空间是否足够。
2.把新的元素,插入到原有的位置
如果把中间的某个元素删除
把后面一位的元素,往前移动一位
3.3简化的for循环
自从Java 5以后,jdk提供了简化的for循环用于输出数组的内容
for( <数据的数据类型> <变量名> : <数组变量名> )
{
//
}
eg.
int[] ar = new ...
for( int i = 0; i < ar.length; i++ )
{
int v = ar[i];
}
上面内容可以简化为:
//简化的for循环只适合读取,不能给数组里面写数据
//好处是不需要声明一个循环计数器
//数组有多少个元素,就循环多少次,每次循环的时候把元素取出下一个放到变量v里面
for( int v : ar )
{
}
四、二维数组
本质上不存在二维数组!全部都是一维数组。
所谓"二维数组",其实是"数组数据类型"的数组。
int -> int[]
int[] 就是int的数组类型
int[][] 就是int数组的数组
理解二维数组的时候,最典型的实体就是电子表格。
4.1动态初始化
//5行3列
int[][] ar = new int[5][3];
//5行,列的数量未知
//每行都没有内容,为null
int[][] ar = new int[5][];
4.2二维数组的使用
// ar1是int[]类型的数组,那么里面装的是int[]类型的数据 int[][] ar1 = newint[5][3];
//获取ar1索引为0的元素,赋予给x变量 //因为ar1里面装的是int[],所以x的类型必须是int[] //取出第0行 //x的使用方法和其他int数组没有任何差别 int[] x = ar1[0];
//5行,列未知 //每行都没有内容,为null int[][] ar2 = newint[5][];
// ar1的长宽已知,[I@表示内存地址 System.out.println( ar1[1] ); // null 表示空,就是未赋予实际的内容 System.out.println( ar2[1] );// null
//给ar2变量里面的第 4 行,赋予一个具体的int[] ar2[4] = newint[]{3,4,5,6,7,8,9}; System.out.println( ar2[1] );// null System.out.println( ar2[4] );// [I@内存地址 |
五、Arrays类
专门用来操作数组的一个工具。使用此类的时候,必须先导入 java.util.Arrays 类。
常用方法
toString : 用于把数组转换为String,通常输出的时候使用。
binarySearch : 使用二分查找法,在数组里面查询指定的元素的位置。使用的时候必须确保数据是有序的。
copyOf : 复制数组用的,性能非常高,因为直接使用系统底层的API,复制堆内存。
copyOfRange : 复制原始数组中的一部分,产生一个新的数组。
parallelSort : 并行排序。在Java 8之前,排序之类的动作只能由一个CPU内核来完成。
并行排序能够同时利用多个CPU内核进行排序,并且排序后把结果汇总一起。
sort: 以前的使用单个CPU核进行排序的方法。
eg.将数组转化为string输出;扩容
import java.util.Arrays;
publicclassTestArrays { publicstaticvoid main(String[] args) { int[] ar = newint[]{13,4,6,8,9};
//把数组里面所有的内容全部输出 // Arrays.toString(ar)是把ar里面的内容转换为String类型,直接输出 System.out.println( Arrays.toString(ar) );
//相当于是扩容 int[] ar1 = Arrays.copyOf(ar, ar.length + 5); System.out.println(ar.length); System.out.println(ar1.length); } }
|
六、获取java的命令行参数
开始运行之前传递进来
在main方法后面的圆括号里面,每次总有一个 String[] args 是固定的,main方法必须有此参数。
这是String[]类型的参数,用于装多个String。
String[] args相当于就是一个变量,这个变量用来装从命令行在启动java命令的时候,传入的命令行参数。
在命令行里输入java <类名> [多个参数,使用空格隔开],空格的数量不限,但是都只认非空格,每组空格间的非空格都是一个参数。
publicclassTestArguments { publicstaticvoid main(String[] args) { //数组的长度就是参数的个数 System.out.println("参数的个数: " + args.length);
//输出所有的参数 for( String s : args ) { System.out.println( s ); } } } |
在命令行里输入
java TestArguments
运行结果
参数的个数:0 |
在命令行里输入
java TestArguments a b cc d
运行结果
参数的个数:4 a b cc d |
运行中传递进来
使用System.in可以获得键盘输入。键盘输入也被称之为"标准输入流"。 System.in
屏幕(cmd)也被称之为"标准输出流"。 System.out
同时屏幕(cmd)也有另外一个作用,叫做"标准错误输出流",专门输出错误信息的。System.err
System.in使用的时候比较麻烦,因为是通过字节( byte[] )的方式来处理数据的。
所以通常接收键盘的输入,会使用Scanner,创建Scanner的时候,需要一个标准的字符输入流。
eg.
//导入
import java.util.Scanner;
//创建实例
//创建一个Scanner,用于读取标准输入流里面的字符串内容
Scanner s = new Scanner( System.in );
import java.util.Scanner;
publicclassTestScanner { publicstaticvoid main(String[] args) { //创建实例 Scanner s = new Scanner( System.in );
//调用next开头的方法,会等待键盘的输入,输入内容以后,遇到回车就会结束next //获得键盘输入的字符串 String c = s.next();
System.out.println( "输入的字符串: " + c );
//等待输入数字。如果输入的字符串无法转换为int,报错 inti = s.nextInt(); System.out.println( "整数: "+ i ); } } |
七、重点
普通的一维数组
动态初始化、静态初始化
获取数组长度
获取数组的元素
给数组里面的元素赋予值
循环输出数组里面所有的内容
普通的for循环
简化的for循环
八、练习
练习1
使用循环给一个长度为20的数组里面的每个元素,填入随机的值。
要使用随机,需要使用 java.util.Random 类的实例
1.在java源代码的第一行写上
import java.util.Random;
2.声明Random类变量,并且创建Random类的实例
Random r = new Random();
3.调用Random实例的nextInt方法产生随机数
int t = r.nextInt();
实现步骤:
1.import
2.在main方法里面new一个Random
3.new一个int数组,长度为20
4.使用for循环给数组里面的每个元素赋予一个随机数
5.使用另外一个循环,计算需要的结果变量(四个)
练习2
把练习1里面的数组里面的值,计算以下几个结果:
1.总和
2.最大值
3.最小值
4.平均值
练习3
计算1~100的阶乘,只需要一个循环即可
练习4
找出1~1000以内的所有完全数
完全数
当一个数的所有真约数(所有的约数里面,除本身之外的约数)的和等于数本身,那么这个数就是完全数。
eg.
6的约数:1/2/3/6
publicclass Wanquanshu { publicstaticvoid main(String[] args) { intsum = 0; for( inti=1; i<=1000; i++ ){ for( intj=1; j<i; j++ ){ if( i%j==0 ){ sum += j; } } if( sum==i ) System.out.println(sum); sum = 0; }
} } |
练习5
把一个数组的内容对调
eg.
int[] ar = new int[]{1,2,3,4,5};
//对调后的结果是 5,4,3,2,1
publicclass duidiao { publicstaticvoid main(String[] args) { int[] ar = newint[]{1,2,3,4,5}; intar_length = ar.length; int[] ar2 = newint[ar_length]; for( inti=0; i<ar_length; i++ ){ ar2[ar_length-i-1] = ar[i]; } } } |
练习6
随机生成数字,检查此数字是否在数组里面已经存在
Random r = new Random();
//生成1~10之间的数字
int t = r.nextInt(10) + 1;
//检查t是否已经在ar里面,如果在则输出已经存在;否则输出不存在。
//如果检查到已经存在则不再继续检查。
int[] ar = new int[]{1,2,4,5,6,8,10};
练习7
生成随机字符
字符的本质就是数字,生成0~25之间的随机数,然后加上小写字母a,那么就变成a~z的字符。
int t = r.nextInt(26);
char c = (char) (t + 'a');
练习8
生成包括A~Z、a~z、0~9之间的6位字符。
aBc61h
8Acl0o
在随机字符的基础上,结合重复检查,实现不重复的随机字符。
package shuzu;
//1.导入Random import java.util.Random; //生成6位随机字符 publicclassRandomChar2 { publicstaticvoid main(String[] args) { //2. Random r = new Random();
//3.放一个共享的数组,里面包含了所有需要的字符 char[] cs = newchar[62]; //3.1.循环给cs变量里面的每个元素赋予一个字符 for(inti = 0; i < 26; i++) { //i = 0 ~ 25 // 把0~25的位置,放小写字母 cs[i] = (char)(i + 'a');
// i + 26 表示 26 ~ 51的范围,放大写字母 cs[i + 26] = (char)(i + 'A');
// 判断i小于10的时候,正好有10个数字,放到最后 // 52 + i if ( i < 10 ) { cs[i + 52] = (char)(i + '0'); } }
//cs是char类型的数组,直接使用System输出,会输出内容 System.out.println( cs );
//4.循环6次,每次循环生成一个数字,这个数字的范围是0~数组长度减一 // 这个数字其实就是数组的索引 for( inti = 0; i < 6; i++ ) { //随机生成cs索引范围的数字,利用这个数字到cs里面获取字符 intindex = r.nextInt( cs.length );
//5.利用生成的随机索引,从数组里面取字符 charc = cs[index]; System.out.print( c ); } System.out.println( ); } } |
练习9
魔术矩阵
在一个二维数组里面,实现每行、每列、对角线的值的和相等。
规则就是不断的往右上角填数
步骤
1.把第一个数放在第一行的最中间
2.把x加一,y减一
如果y小于0,那么就把y的值设置为行数减一
如果x大于长度,那么就把x的值设置为0
3.如果当前填的数是行数的整数倍,那么不要进行第二步。
直接y加一
ar[y][x] = 数
相关文章
- 暂无相关文章
用户点评