【数组定义】:
数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。每一个数据称作一个元素,每个元素通过一个索引(下标)进行访问。
【特点】:
dataType[] arrayRefVar;//首选
//或
dataType arrayRefVar[];//效果相同,但不是首选方法
【注意点】:
dataType[] arrayRefVar = new dataType[arraysize];
arrays.length
创建一个数组的步骤:
//1、定义,声明一个数组
int[] s;
//int nums[];
//2、创建数组,给数组分配空间
s = new int[10];
//3、给数组元素赋值;数组是对象,数组中的元素就是对象的属性
for (int i = 0; i < 10; i++) {
s[i] = 2 * i + 1;//给数组元素赋值; 数组是对象,数组中的元素就是对象的属性
}
【java内存】:
1、堆:
2、栈
3、方法区
【创建引用型一维数组】
public class Application {
public static void main(String[] args) {
Man[ ] mans; //声明引用类型数组;
mans = new Man[10]; //给引用类型数组分配空间;
Man m1 = new Man(1,11);
Man m2 = new Man(2,22);
mans[0]=m1;//给引用类型数组元素赋值;
mans[1]=m2;//给引用类型数组元素赋值;
}
}
class Man{
private int age;
private int id;
public Man(int id,int age) {
super();
this.age = age;
this.id = id;
}
}
int[] nums = new int[10];
静态初始化
除了用 new 关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值
//创建+赋值
int[] a = {1,2,3};
Man[] mans = {new Man(1,1),newMan(2,2)};
动态初始化
数组定义与为数组元素分配空间并赋值的操作分开进行
//包含默认初始化
int[] a = new int[10];
a[0] = 1;
a[1] = 2;
默认初始化
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化
int a2[ ] = new int[2]; // 默认值:0,0
boolean[ ] b = new boolean[2]; // 默认值:false,false
String[ ] s = new String[2]; // 默认值:null, null
(遍历、拷贝最常见)
【数组的遍历】
for循环:数组元素下标的合法区间:[0, length-1]。可以通过下标来遍历数组中的元素,遍历时可以读取元素的值或者修改元素的值。
int[ ] a = new int[4];
//初始化数组元素的值
for(int i=0;i<a.length;i++){
a[i] = 100*i;
}
//读取元素的值
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
for-each 循环:增强 for 循环 for-each 是 JDK1.5 新增加的功能,专门用于读取数组或集合中所有的元素,即对数组进行遍历。
//翻转数组
public static int[] reverse(int[] array){
int[] res = new int[array.length];
for (int i = 0,j = array.length-1;i< res.length;i++,j--){
res[i] = array[j];
}
return res;
}
//遍历
public static void printarray(int[] array){
for (int x : array) {
System.out.print(x+" ");
}
}
【数组的拷贝】
System 类中的 static void arraycopy(object src,int srcpos,object dest, int destpos,int length)方法可以将 src 数组里的元素值赋给 dest 数组的元素,其中 srcpos 指定从 src 数组的第几个元素开始赋值,length 参数指定将 src 数组的多少个元素赋给 dest 数组的元素。
String[ ] s = {"张三","李四","王五","小明","小红"};
String[ ] sBak = new String[6];
System.arraycopy(s,0,sBak,1,s.length);
for (int i = 0; i < sBak.length; i++) {
System.out.print(sBak[i]+ "\t");
}//null 张三 李四 王五 小明 小红
JDK 提供的 java.util.Arrays 类,包含了:排序、查找、填充、打印内容等常见的操作。
int[ ] arr = {1,2,323,23,543,12,59};
//打印数组元素Arrays.toString
Arrays.toString(arr);
//数组排序:升序Arrays.sort
Arrarys.sort(a);
//数组填充 fill
Arrays.fill(arr,11);
Arrays.fill(arr,2,5,11);将2到5索引的元素替换为11
//使用二分法查找,必须先对数组进行排序
//返回排序后新的索引位置,若未找到返回负数
Arrays.binarySearch(arr, 12));
【Comparable 接口】
对某个类的对象之间做比较,可以通过Comparable 接口实现。接口中只有一个方法compareTo,这个方法定义了对象之间的比较规则
public int compareTo(Object obj) //obj 为要比较的对象
将当前对象和 obj 这个对象进行比较,如果大于返回 1,等于返回 0,小于返回-1.
public int compareTo(Object obj) {
Man man = (Man) obj;
if (this.age < man.age) {
return -1;
}
if (this.age > man.age) {
return 1;
}
return 0;
}
class Man implements Comparable{
int age;
int id;
String name;
public Man(int age, String name) {
super();this.age = age;
this.name = name;
}
public String toString() {
return this.name;
}
public int compareTo(Object o) {
Man man = (Man) o;
if (this.age < man.age) {
return -1;
}
if (this.age > man.age) {
return 1;
}
return 0;
}
}
public class Test {
public static void main(String[ ] args) {
Man[ ] msMans = { new Man(3, "a"), new Man(60, "b"), new Man(2, "c") };
Arrays.sort(msMans);
System.out.println(Arrays.toString(msMans));
}
}
多维数组可以看成以数组为元素的数组(数组的数组),eg:二维数组的每一个元素都是一个一维数组。
int a[][] = new int[2][5];
for (int i = 0;i< array.length;i++){
for (int j = 0;j<array[i].length;j++){
System.out.print(array[i][j]+" ");
}
}
【二维数组的声明】
// Java中多维数组的声明和初始化应按从低维到高维的顺序进行
int[ ][ ] a = new int[3][ ];
a[0] = new int[2];
a[1] = new int[4];
a[2] = new int[3];
// int a1[ ][ ]=new int[ ][4];//非法
【二维数组的静态初始化】
int[ ][ ] a = { { 1, 2, 3 }, { 3, 4 }, { 3, 5, 6, 7 } };
System.out.println(a[2][3]);
【二维数组的动态初始化】
int[ ][ ] a = new int[3][ ];
// a[0] = {1,2,5}; //错误,没有声明类型就初始化
a[0] = new int[ ] { 1, 2 };
a[1] = new int[ ] { 2, 2 };
a[2] = new int[ ] { 2, 2, 3, 4 };
System.out.println(a[2][3]);//4
System.out.println(Arrays.toString(a[0]));//[1,2]
System.out.println(Arrays.toString(a[1]));//[2,2]
System.out.println(Arrays.toString(a[2]))//[2,2,3,4]
【获取数组长度】
//获取的二维数组第一维数组的长度。
System.out.println(a.length);
//获取第二维第一个数组长度。
System.out.println(a[0].length);
1、向数组末尾添加/删除一个元素
push() // 向数组末尾添加一个元素
pop() // 删除数组最后一个元素
2、向数组开头添加/删除一个元素
unshift() // 向数组开头添加一个元素
shift() // 删除数组开头第一个元素
3、对两个数组进行拼接concat()
也可以使用扩展运算符
//arr.concat(['你', '好'], ['欢', '迎'])
4、**对数组进行截取splice() **
当第二个参数不传的时候直接从开始的索引截取到最后一个,直接改变原数组
arr.splice(开始的索引, 截取多少个, 要插入的元素可以不传)
5、截取数组中的值slice()
当第二个参数不传的时候直接从开始的索引截取到最后一个,不改变原数组
arr.slice(开始的索引,结束的索引);
6、**数组排序sort() **
arr.sort();
7、**反转数组reverse() **
arr.reverse();
8、字符连接join()
arr.join(以什么字符链接);
9、查找数据当中有没有该元素
includes()
includes() 可以查找出数据当中有没有该元素,使用indexOf也可以
区别:
通过动画可视化数据结构和算法 - VisuAlgo
for (int i = 0 ;i< array.length-1;i++){
for (int j = 0;j<array.length-1-i;j++){
if (array[j]<array[j+1]) {
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
优化
1.整个数列分成两部分:前面是无序数列,后面是有序数列。
2.初始状态下,整个数列都是无序的,有序数列是空。
3.每一趟循环让无序数列中最大数排到最后,(有序数列的元素个数增加1)
4.每一趟循环都从数列的第一个元素开始进行比较,依次比较相邻的两个元素,比较到无序数列的末尾即可(而不是数列的末尾);如果前一个大于后一个,交换。
5.判断每一趟是否发生了数组元素的交换,如果没有发生,则说明此时数组已经有序,无需再进行后续趟数的比较了。此时可以中止比较。
// 外层循环:n个元素排序,则至多需要n-1趟循环
for (int i = 0 ;i< array.length-1;i++){
// 定义一个布尔类型的变量,标记数组是否已达到有序状态
boolean flag = false;//通过flag标志位减少没有意义的比较
/*内层循环:每一趟循环都从数列的前两个元素开始进行比较,比较到无序数组的最后*/
for (int j = 0;j<array.length-1-i;j++){
// 如果前一个元素大于后一个元素,则交换两元素的值;
if (array[j]<array[j+1]) {
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
//本趟发生了交换,表明该数组在本趟处于无序状态,需要继续比较;
flag = true;
}
}
//根据标记量的值判断数组是否有序,如果有序,则退出;无序,则继续循环
if (flag == false)
break;
}
基本思想是设数组中的元素从小到大有序地存放在数组(array)中,首先将给定值 key 与数组中间位置上元素的关键码(key)比较,如果相等,则检索成功;
否则,若 key 小,则在数组前半部分中继续进行二分法检索;
若 key 大,则在数组后半部分中继续进行二分法检索。
//Arrays.sort(arr);
//二分法查找之前,先要对数组元素排序
int low = 0;
int high = array.length - 1;
while(low <= high){
int middle = (low + high) / 2;
if(value == array[middle]){
return middle; //返回查询到的索引位置
}
if(value > array[middle]){
low = middle + 1;
}
if(value < array[middle]){
high = middle - 1;
}
}
return -1; //上面循环完毕,说明未找到,返回-1
//1.创建一共11×11的二维数组
//0:没有;1:白棋;2:黑棋
int[][] arr = new int[11][11];
arr[1][2] = 1;
arr[2][3] = 2;
System.out.println("输出原始的数组");
for (int[] Ints : arr){
for (int anInt : Ints){
System.out.print(anInt+"\t");
}
System.out.println();
}
//转换为稀疏数组
//遍历获取有效值的个数
int sum = 0;
for (int[] Ints : arr){
for (int anInt : Ints){
if (anInt!=0) sum++;
}
}
System.out.println("有效值个数为:"+sum);
//创建一个稀疏数组
int[][] arr2 = new int[sum+1][3];
arr2[0][0] = 11;
arr2[0][1] = 11;
arr2[0][2] = sum;
//遍历二维数组,将非零值存入稀疏数组
int k = 0;
for (int i =0;i<arr.length;i++)
for (int j =0;j<arr[i].length;j++){
if (arr[i][j] != 0){
k++;
arr2[k][0] = i;
arr2[k][1] = j;
arr2[k][2] = arr[i][j];
}
}
System.out.println("稀疏数组表示为:");
for (int[] Ints : arr2){
for (int anInt : Ints)
System.out.print(anInt+"\t");
System.out.println();
}
//还原稀疏数组
int[][] rearray = new int[newarray[0][0]][newarray[0][1]];
for (int i = 1;i< newarray.length;i++){
rearray[newarray[i][0]][newarray[i][1]] = newarray[i][2];
}
for (int[] Ints : rearray){
for (int anInts:Ints){
System.out.print(anInts+"\t");
}
System.out.println();
}