什么是数组
所谓数组,是有序的元素序列。 [1] 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按无序的形式组织起来的一种形式。 [1] 这些无序排列的同类数据元素的集合称为数组。
数组的定义
int [] array1 = {1,2,3,4,5};
int [] array2 = new int[]{1,2,3,4,5};//“new”:生成一个对象
int [] array3 = new int[5];//“引用”:用来存放对象的地址
1.当定义好一个数组之后,没有初始化,默认值为0;若数组为引用类型,默认值为null
2.java中没有按值传递
3.“java.lang.ArrayIndexOutOfBoundsException:”:数组定义异常
数组的访问
for(int i=0;i<array2.length;i++){//length:数组的一个属性
System.out.println(array2[i]);
}//for循环,通过数组下标访问数组
for(int i:array1){//"for(表达式1:表达式2)":foreach
System.out.println(i+" ");
}//foreach:不能通过数组下标访问数组
/*
System.out.println(array1);
//“[I@816f27d”:地址的哈希码
*/
1.空指针异常
/*
int[] array4 = null;
System.out.println(array4.length);//java.lang.NullPointerException:空指针异常
String a = null;
System.out.println(a.length());//java.lang.NullPointerException:空指针异常
*/
数组的拷贝
int [] array = {1,2,3,4,5};
int [] array0 = array;//不是拷贝
int [] array1 = new int [array.length];
int [] array2 = new int [array.length];
for(int i=1;i < array.length;i++){
array1[i] = array[i];
}
for(int i:array1){
System.out.print(i+" ");
}//方法一
System.out.println();
System.arraycopy(array,0,array1,0,array.length);//被native所修饰的方法(快)
for(int i:array2){
System.out.print(i+" ");
}//方法二
System.out.println();
int []array3 = Arrays.copyOf(array,array.length);//调用了System.arraycopy
for(int i:array3){
System.out.print(i+" ");
}//方法三
System.out.println();
int []array4 = array.clone();
for(int i:array4){
System.out.print(i+" ");
}//方法四
1.for循环
2.System.arraycopy(array,0,array1,0,array.length),被native所修饰的方法(快),底层由C\C++实现
3.int []array3 = Arrays.copyOf(array,array.length);调用了System.arraycopy
4.int []array4 = array.clone();
以上4种拷贝方式如果数组中是简单类型是深拷贝, 即又创建了一个数组对象, 拷贝原有数组中的所有元素到新数组中. 因此, 修改原数组, 不会影响到新数组.
如果数组中是引用类型则属于浅拷贝:即修改原数组同时修改新数组
深拷贝:
浅拷贝:
深拷贝修改:
将数组转换为字符串
import java.util.Arrays;
public class Test {
public static String toString1(int [] b) {//将数组转换为字符串
String s1 ="[" ;
for(int i=0;i<b.length;i++){
s1 += b[i];// 借助 String += 进行拼接字符串
if(i != b.length-1){
s1 += ",";
}
}
s1 +="]" ;
return s1;
}
public static int [] func(int [] a){
int x[] = new int[a.length];
for(int i=0;i<a.length;i++){
x[i] = 2*a[i];
}
return x;
}
public static void main(String[] args) {
int [] array = {1,2,3,4,5};
int [] array2 = func(array);
for(int i:array){
// System.out.println(i+" ");
}
for(int i:array2){
// System.out.println(i+" ");
}
String s = Arrays.toString(array);//内置函数方式
System.out.println(s);
String s2 = toString1(array);//函数方式
System.out.println(s2);
}
}
冒泡排序和二分查找
public static int max(int[] a) {
int ret;
for(int i = 0;i<a.length-1;i++){
for(int j=0;j<a.length-1;j++)
if(a[j]>a[j+1]){
ret = a[j];
a[j] = a[j+1];
a[j+1] = ret;
}
}//冒泡排序
return a[a.length-1];
}
public static int binarSearch(int[] a,int k) {
int l = 0;
int r = a.length-1;
while(l<=r){
int mid = (l+r)/2;
if(a[mid]>k){
l = mid+1;
}else if(a[mid]<k){
r = mid-1;
}else if(a[mid] == k){
return mid;
}
}
return -1;
}//二分查找
二维数组定义
int [][] array = {{1,2},{1,2},{4,4}};
System.out.println(Arrays.deepToString(array));//深度打印二维数组
System.out.println(array[1]);
Arrays.sort(array[2],0,array.length);
System.out.println(Arrays.deepToString(array));
}
内存分析
程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址.
虚拟机栈(JVM Stack): 重点是存储局部变量表(当然也有其他信息). 我们刚才创建的 int[] arr 这样的存储地址
的引用就是在这里保存.
本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部
变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的.
堆(Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2,
3} )
方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据.
方法编译出的的字节码就是保存在这个区域.
运行时常量池(Runtime Constant Pool): 是方法区的一部分, 存放字面量与符号引用.//在JDK1.7之前,常量池在方法区里,在JDK1.7之后,常量池移到了堆里
Native 方法:
JVM 是一个基于 C++ 实现的程序. 在 Java 程序执行过程中, 本质上也需要调用 C++ 提供的一些函数进行和操作
系统底层进行一些交互. 因此在 Java 开发中也会调用到一些 C++ 实现的函数.
这里的 Native 方法就是指这些 C++ 实现的, 再由 Java 来调用的函数.