一旦数组的初始化完成,数组在内存中所占的空间将被固定下来,因此数组的长度将不可变。即使把某个数组元素的数据清空,但它所占的空间依然被保留,依然属于该数组,数组的长度依然不变。
Java的数组既可以存储基本数据类型也可以存储引用数据类型,只要所有的数组元素具有相同的类型即可。数组也是一种数据类型,它本身是一种引用类型。
Java语言支持两种语法格式来定义数组
type[ ] arrayName;
type arrayName [ ];
通常推荐使用第一种。
定义数组的时候不能指定数组的长度。数组定义后 ,必须对数组初始化后才可以使用。数组定义的时候并未指向任何有效的内存空间,所以还没有内存空间来存储数组元素。
数组的初始化
Java语言中数组必须先初始化 ,然后才可以使用,所谓的初始化 就是为数组的元素分配内存空间,并为每个数组元素赋初值。
静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度。
动态初始化:初始化的时候程序员只指定数组的长度,由系统为数组元素分配初始值。
Java的内存分配
Java对内存空间的划分:五部分:栈,堆,方法区,本地方法区,寄存器。
栈内存:存储都是局部变量。只要是在方法中定义的变量都是局部变量。一旦变量的生命周期结束该变量就被释放。
堆内存:存储都是实体(对象),每一个实体都有一个首地址值。堆内存的变量都有默认初始化值。不同类型不一样。int-0 double-0.0 boolean-false char-'\u0000'。当实体不在使用时,就会被垃圾回收机制处理。
数组使用:
1、将数组转成字符串
需求:将数组中的时间编程字符串输出。如[12,22,13,18,15] 反转后”15,18,13,22,12”
思路:简单的方式就是利用了字符串和任何数据相加都是相连接。
步骤:
明确1:结果?字符串。
明确2:参数?数组。
1、定义字符串变量。
2、遍历数组。将每一个数组的元素和字符串相连接。
3、判断,不是最后一个元素,后面连接逗号,是最后一个元素,后面不连接逗号。
4、将连接后的字符串返回。
class ArrayTest3
{
public static void main(String[] args)
{
int[] arr = {12,22,13,18,15};
String str = toString(arr);
System.out.println(str);
}
public static String toString(int[] arr)
{
//1,定义字符串变量。
String temp = "[";
//2,遍历数组。将每一个数组的元素和字符串相连接。
for(int x = 0; x < arr.length; x++)
{
//3,判断,不是最后一个元素,后面连接逗号,是最后一个元素,后面不连接逗号。
if(x!=arr.length-1)
temp = temp + arr[x] + ",";
else
temp = temp + arr[x] + "]";
}
//4、将连接后的字符串返回。
return temp;
}
}
2、数组反转
需求:将数组中的数据进行反转,如[12,22,13,18,15] 反转后[15,18,13,22,12]
思路:
1、需要定义数组反转的功能:
明确1:结果?无,void。
明确2:参数?数组。
2、数组反转,就是将数组中的值进行位置互换。
互换的条件是:0角标和length-1角标位置上的值互换
1角标和length-2角标位置上的值互换
以此类推
3、互换到什么时候停止呢?只要头角标大于等于了尾角标就停止。
4、怎么互换呢?互换就是交换两个空间中的值,可以使用第三方变量。
步骤:
1、定义功能,接受数组
2、遍历数组,每遍历一次交换数组两个位置的上的值,start代表头角标,end代表尾角标
3、交换每次遍历的两个空间中的数据
class ArrayTest4
{
public static void main(String[] args)
{
int[] arr = {12,22,13,18,15};
printArray(arr);
reverseArray(arr);
printArray(arr);
}
//1、定义功能,接受数组
public static void reverseArray(int[] arr)
{
//2、遍历数组,每遍历一次交换数组两个位置的上的值,
// start代表头角标,end代表尾角标
for (int start = 0,end=arr.length-1;start<end ;start++,end-- )
{
//3、交换每次遍历的两个空间中的数据
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
}
//此功能为打印数组
public static void printArray(int[] arr)
{
for (int i=0;i<arr.length ;i++ )
{
if(i!=arr.length-1)
System.out.print(arr[i]+",");
else
System.out.println(arr[i]);
}
}
}
十进制-->十六进制。
思路:在前面讲解时,使用的&15(0B1111)运算每次可以取出十进制的最低四位数值,并将其打印在控制台上,遇到了两个问题,数据顺序反。同时还会有打印出多个0.
分析数据顺序反的原因是&15运算要执行多次,每次都将运算结果直接打印在控制台,若将这些值直接存储在容器中,存完之后按照相反的顺序打印出来,那么看到的数据就是正确的。
解决方式:
1、顺序反?每运算出一位,不要打印,先存储。需要容器。
2、去除零?需要转换的数据会不断的右移,如果右移后剩余的二进制都是0,
也就是没有有效位,就不需要进行&运算了。也就是不需要在往数组中存储了。
class ArrayTest6
{
public static void main(String[] args)
{
int num = 60;
String str_hex = toHex(num);
System.out.println(str_hex);
}
public static String toHex(int num)
{
//1,定义容器。存储的是字符,长度为8.一个整数最多8个16进制位。
char[] chs = new char[8];
//2,定义一个用于操作数组的索引。
int index = chs.length;
while(num!=0)
{
int temp = num & 15;
if(temp > 9)
chs[--index] = ((char)(temp-10+'A'));
else
chs[--index] = ((char)(temp+'0'));
num = num >>> 4;
}
System.out.println("index="+index);
return "0x"+toString(chs,index);
}
//定义一个功能,将字符数组转成字符串。
public static String toString(char[] arr,int index)
{
String temp = "";
for(int x=index; x<arr.length; x++)
{
temp = temp + arr[x];
}
return temp;
}
}
需求3
十进制-->十六进制(查表法)
思路:
十进制转成十六进制的每一位都是十六进制元素中的某一个。十六进制的元素有很多固定个数。而且还有对应的编号。所以可以使用查表法!
class ArrayTest7
{
public static void main(String[] args)
{
int num = 26;
String str_hex = toHex(num);
System.out.println("hex:"+str_hex);
}
public static String toHex(int num)
{
//1,建立表。
char[] chs = {'0','1','2','3'
,'4','5','6','7'
,'8','9','A','B'
,'C','D','E','F'};
//2,创建临时容器。
char[] arr = new char[8];
//3,创建操作临时容器的角标。
int index = arr.length;
//4,通过循环对num进行& >>等运算。
while(num!=0)
{
//5,对num进行&运算。
int temp = num & 15;
//6,根据&运算后的结果作为角标查表,获取对应的字符。并将字符存储到临时容器中。
arr[--index] = chs[temp];
//7,对num进行右移。
num = num >>> 4;
}
return "0x"+toString(arr,index);
}
//定义一个功能,将字符数组转成字符串。
public static String toString(char[] arr,int index)
{
String temp = "";
for(int x=index; x<arr.length; x++)
{
temp = temp + arr[x];
}
return temp;
}
}
冒泡排序
冒泡排序算法原理:这种算法和生活中常见的水中气泡的浮沉类似。
数组冒泡算法(从小到大):
第一轮:数字第一个空间值和第二个空间值比较,把较大的值存在第二个空间中,接着第二个空间值和第三个空间值作比较,较大的值存在第三个空间中,以此类推直到倒数第二个空间和倒数第一个空间比较,把较大值存放在最后一个空间中。
第二轮:由于最后一个空间已经是最大值了,那么第二轮算法和第一轮一样,只是最后一次比较是倒数第三个空间和倒数第二个空间比较。把较大的值存在倒数第二个空间中。
以此类推。
/*
冒泡排序。
*/
public static void bubbleSort(int[] arr)
{
for(int x=0; x<arr.length-1; x++)
{
for(int y=0; y<arr.length-1-x; y++)
{
if(arr[y]>arr[y+1])
{
int temp = arr[y];
arr[y] = arr[y+1];
arr[y+1] = temp;
}
}
}
}
折半查找
折半查找,必须保证数组已经是有序的。
思路:
1,通过角标先获取中间角标上元素。
2,让该元素和要找的数据比较。
3,如果要找的数大了,缩小范围,要找的范围应该是 中间的角标+1---尾角标。
如果要找的数小了,要找的范围 头角标---中间角标-1;
4,不断如此重复,就可以找到元素对应的角标。
public static int binarySearch(int[] arr,int key)
{
//1,定义三个变量,记录头角标,尾角标,中间角标。
int max,min,mid;
min = 0;
max = arr.length-1;
mid = (max+min)>>1;
while(arr[mid]!=key)
{
if(key>arr[mid])
min = mid + 1;
else if(key<arr[mid])
max = mid - 1;
//判断元素是否存在。
if(max<min)
return -1;
mid = (max+min)>>1;
}
return mid;
}
Java 8 增强的工具类 Arrays
。。。。