此文来源于尚学堂培训
数组的初始化
1:数组的动态初始化。
int[] scores = new int[10];
可以声明和初始化分开进行。
int[] scores;
scores = new int[10];
2:数组的静态初始化:
int[] scores = new int[]{1,2,3,324,2,32,21,342,24};
int[] scores;
scores = new int[]{1,2,3,324,2,32,21,342,24};
3:更加简便的语法:糖语法。
数组常量,声明和赋值必须同时进行。
int[] scres = {1,2,3,324,2,32,21,342,24};
数组的特点
1:数组可以存储多个数据,数据的类型必须一致。一个数组只能存储一种数据类型的数据。 所有元素类型相同。
2:数组的元素在堆中连续存储。每一个元素占据的空间,与元素类型需要的空间相同。
3:数组元素的下标从0开始,0序的。元素通过 数组名+下标 访问。访问元素就像访问普通的变量一样一样的。
4:数组有一个属性 length 代表了数组的元素的个数。通过数组名+点‘.’引用符访问,【.length】 也就是数组的长度。最大数组下标为 【数组名.length -1】。
5:数组定位某一个元素的时候效率很高。 如果访问下标为n的元素 通过 首地址+元素类型的字节数*n 可以迅速定位元素位置。
6:数组的长度一旦确定了,就不能在更改了。
数组常用排序方法
1.冒泡排序
public static void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
boolean flag = true;//设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已然完成。
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr,j,j+1);
flag = false;
}
}
if (flag) {
break;
}
}
}
2.选择排序
for(int i=0;i<array.length;i++){
int min=i;
for(int j=i+1;j<array.length;j++){
if(array[j]<array[min]){
min=j;
}
}
int temp=array[min];
array[min]=array[i];
array[i]=temp;
}
3.插入排序
for(int i=1;i<array.length;i++){
for(int j=i;j>0&&array[j]<array[j-1];j--){
int temp=array[j];
array[j]=array[j-1];
array[j-1]=temp;
}
}
数组的优点
1:数组可以存储多个数据(元素)。
2:根据下标访问元素效率比较高。数组在堆中元素连续存储。
3:根据下标遍历数组元素效率较高。
缺点;
1:删除,插入,效率比较低。根据内容查找元素效率也比较低。
2:数组只能存储一种数据类型的。
3:数组的长度一旦确定了,就不能在更改了。不能自动扩容。//int[] ints = new int[3]; ints = new int[5];//数组引用变量的复用。
4:数组的封装程度比较低。数组没有提供一些针对数组操作的一些方法。想实现任何的关于数组的功能,都需要自己实现。
Arrays 工具类
常用的方法:
binarySearch(byte[] a, byte key) 使用二分搜索法来搜索指定的 byte 型数组,以获得指定的值。
equals(boolean[] a, boolean[] a2)
如果两个指定的 boolean 型数组彼此相等,则返回 true。
sort(byte[] a)
对指定的 byte 型数组按数字升序进行排序。
toString(boolean[] a)
返回指定数组内容的字符串表示形式。
变参 jdk 1.5 开始支持可变参数
语法:
public static int add(int ... ints){
}
上述的方法可以接收任意个int类型的参数作为实参。
1:可以接收任意个参数[0-n],类型要和参数类型兼容
2:变参可以当作数组来处理,底层就是使用数组实现。
3: 变参参数只能出现在方法参数列表的末尾。
4:参数列表只能最多有个一个变参参数。
5: 如果变参方法和定参方法同时存在,优先调用匹配定参的方法执行。
6:变参参数 的实现的本质就是使用同类型的一维数组实现。所以不能在同一个类内,定义add(int ... ints) 和 add(int[] ints) 这两种形式。
7:变参参数可以接收同类型的数组作为实参。
总结:变参参数和数组作为参数的相同点和不同点
相同点:
1:都是使用数组来进行处理。
2:只能处理同种类型的数据。
3:变参和数组参数都可以接收数组作为实参。
不同点:
1:变参参数既可以接收任意个该类型的数据作为实参,还可以使用数组作为实参。 。数组作为参数,只能使用数组作为实参。
2:数组作为形参,那么形参的位置是随意的。 变参的形参只能放到参数列表的末尾。
二维数组
int[] ints;
int i;
多维数组其实本身还是一维数组。只不过一维数组中的每一个元素又是数组类型了。
初始化
二维数组的声明和动态初始化。声明和初始化可以分开进行。
//最常见的形式。
int[][] intss = new int[3][3];
静态初始化,,
int[][] intss = new int[][]{
{1,2},//最终的一维数组的元素的个数,可以相同,可以不同。
{1},
{123,45}
};
糖语法
int[][] intss = {
{1,2},
{1},
{123,45}
};
//变种
int[] ints[] = new int[1][1];
//二维数组,高纬和低纬,可以分开进行初始化。
螺旋二维数组
public class TestArray11{
public static void main(String[] args){
int count = 6;
int[][] ints = test(count);
for (int i = 0; i < count; i++) {
for (int j = 0; j < count; j++) {
System.out.print(ints[i][j] + "\t");
}
System.out.println();
}
}
private static int[][] test(int count){
int[][] ints = new int[count][count];
final int RIGHT = 0;
final int DOWN = 1;
final int LEFT = 2;
final int UP = 3;
int dir = RIGHT;
int curRow = 0;
int curCol = 0;
for (int i = 1; i <= count * count; i++) {
switch(dir){
case RIGHT:
if(curCol < count){
if(ints[curRow][curCol] == 0){
ints[curRow][curCol] = i;
curCol ++;
}else{
curCol --;
dir = DOWN;
if(ints[curRow + 1][curCol] != 0){
return ints;
}else{
curRow ++;
ints[curRow][curCol] = i;
curRow ++;
}
}
}else{
curCol --;
dir = DOWN;
if(ints[curRow + 1][curCol] != 0){
return ints;
}else{
curRow ++;
ints[curRow][curCol] = i;
curRow ++;
}
}
break;
case DOWN:
if(curRow < count){
if(ints[curRow][curCol] == 0){
ints[curRow][curCol] = i;
curRow ++;
}else{
curRow --;
dir = LEFT;
if(ints[curRow][curCol-1] != 0){
return ints;
}else{
curCol --;
ints[curRow][curCol] = i;
curCol --;
}
}
}else{
curRow --;
dir = LEFT;
if(ints[curRow][curCol-1] != 0){
return ints;
}else{
curCol --;
ints[curRow][curCol] = i;
curCol --;
}
}
break;
case LEFT:
if(curCol >=0){
if(ints[curRow][curCol] == 0){
ints[curRow][curCol] = i;
curCol --;
}else{
dir = UP;
curCol ++;
if(ints[curRow - 1][curCol] != 0){
return ints;
}else{
ints[--curRow][curCol] = i;
curRow --;
}
}
}else{
curCol ++;
dir = UP;
if(ints[curRow - 1][curCol] != 0){
return ints;
}else{
ints[--curRow][curCol] = i;
curRow --;
}
}
break;
case UP:
if(curRow >=0){
if(ints[curRow][curCol] == 0){
ints[curRow][curCol] = i;
curRow --;
}else{
dir = RIGHT;
curRow++;
if(ints[curRow][curCol+1] != 0){
return ints;
}else{
ints[curRow][++curCol] = i;
++curCol;
}
}
}else{
curRow ++;
dir = RIGHT;
if(ints[curRow][curCol+1] != 0){
return ints;
}else{
ints[curRow][++curCol] = i;
++curCol;
}
}
break;
}
}
return ints;
}
}
自己实现二分法查找
import java.util.Arrays;
public class TestBinarySearch{
public static void main(String[] args){
final int MAX = 20000;
int[] ints = getArray(MAX,0,MAX);
print(ints);
int key = 19996;
Arrays.sort(ints);
print(ints);
System.out.println("index = " + myBinarySearch(ints , key));
;
}
public static void print(int[] array){
System.out.println(Arrays.toString(array));
}
public static int[] getArray(int length,int min,int max){
int[] ints = new int[length];
//随机赋值
for(int i = 0 ;i < length; i++){
ints[i] = (int)(Math.random()*(max - min))+min;
}
return ints;
}
//思路:通过每次循环,重新确定查找的区间范围,不停的缩减范围,直到找到最后的数据。
public static int myBinarySearch(int[] array, int key){
int len = array.length;
int insertIndex = len>>1;
final int firstInsertIndex = insertIndex;
int startIndex = 0;//查找的开始索引
int endIndex = len-1;//查找的结束索引。
int counter = 0;
while(endIndex >= startIndex){
counter ++;
if(array[insertIndex] > key){
endIndex = insertIndex - 1;
}else if(array[insertIndex] < key){
startIndex = insertIndex + 1;
}else{
System.out.println("counter = "+counter);
return insertIndex;
}
//first
insertIndex = (endIndex-startIndex) /2 + startIndex;
}
System.out.println("counter = "+counter);
return - firstInsertIndex - 1;
}
}