黑马程序员_编程基础之第三篇---java语言基础三
01-数组(静态初始化---常见问题)
1.概念
同一种类型的集合,其实数组就是一个容器。
2.数组的好处
可以自动给数组中的元素从0开始编号,方便操作这些元素。
3.数组的定义及赋值格式
格式1:
元素类型[] 数组名=new 元素类型[元素个数或数组长度];
int[] sz=new int[3];
int sz[]=new int[3];
sz[0]=1;
sz[1]=4;
sz[2]=5;
格式2:
数据明确情况下可以使用
元素类型[] 数组名=new 元素类型[]{元素,元素....};
int[] arr=new int[]{2,3,4,5};
int[] arr={1,3,4,5};简化形式
4.数组在操作当中常见的问题,这个要做必要掌握
/*
1.
数组的定义及赋值
返回结果为4
int[] arr1=new int[3];
arr1[0]=1;
arr1[1]=3;
arr1[2]=4;
System.out.print(arr1[2]);
*/
/*2.
数组的定义
返回结果为0
原因----数组的默认初始化值为0
int[] arr2=new int[3];
System.out.print(arr2[2]);
*/
/*3.
数组的定义
程序无返回结果
原因----java.lang.ArrayIndexOutOfBoundsException:3(操作数组时访问到了数组中不存在的脚标)
int[] arr3=new int[3];
System.out.print(arr3[3]);
注意:此程序编译时不会报错,因为编译时只检查语法错误
*/
/*4.
数组的定义
程序无返回结果
原因----java.lang.NullPointerException(空指针异常,arr4这个引用不再指向任何实体,
因此不能操作arr4[2])
空指针异常:当引用没有任何指向值为null的情况,该引用还在用于操作实体。
int[] arr4=new int[3];
arr4=null;
System.out.print(arr4[2]);
注意:此程序编译时不会报错,同样是因为没有语法错误
*/
02-数组(常见操作-遍历)
数组的操作:获取数组中的元素最为常见
/*1.获取数组中的元素之1----数组中的单个元素
int[] arr2=new int[3];
System.out.print(arr2[1]);*/
/*2.获取数组中的元素之2----数组中的多个元素
int[] arr2=new int[3];
System.out.print("arr2["+0+"]="+arr2[0]);
System.out.print("arr2["+1+"]="+arr2[1]);
System.out.print("arr2["+2+"]="+arr2[2]);*/
/*3.如果数组中存在多个元素时,获取数组中的元素通常会用到遍历。
情况之一:数组元素确定时
int[] arr3=new int[3];
for(int x=0;x<3;x++)
{
System.out.println("arr3["+x+"]="+arr3[x]+";");
}*/
/*4.如果数组中存在多个元素时,获取数组中的元素通常会用到遍历。
情况之二:数组元素不确定时
数组中有一个属性可以直接获取到数组元素个数length
使用方式:数组名称.length
int[] arr3=new int[]{1,3,5,6,2,8};
for(int x=0;x<arr3.length;x++)
{
System.out.println("arr3["+x+"]="+arr3[x]+";");
}
*/
但凡有数组,通常都要用到遍历;
//练习1:累加和
int[] arr3=new int[]{1,3,5,6,2,8};
int sum=0;
for(int x=0;x<arr3.length;x++)
{
sum+=arr3[x];
System.out.println("arr3["+x+"]="+arr3[x]+";");
}
//练习2:打印一个数组元素,并用逗号隔开。
int[] arr=new int[]{1,3,2,4,5,6};
printArray(arr);
}
public static void printArray(int[] arr)
{
for(int x=0;x<arr.length;x++)
{
if(x!=arr.length-1)//长度-1便是数组中最后一个元素
System.out.print(arr[x]+",");
else
System.out.println(arr[x]); }
}
03-数组(常见操作-获取最值)
class Sz3
{
/*给定一个数组{5,1,4,6,2,8,9}
要求:获取数组中的最大值,以及最小值
1.获取数组中的最大值
思路:
1.获取最值需要进行比较。每一次比较都会有一个较大的值,因为该值不确定,通过一个变量进行临时存储。
2.让数组中的每一个元素都和这个变量中的值进行比较。
如果大与变量中的值,就用该变量记录较大值。
3.当所有的元素都比较完成,那么该变量中存储的就是数组中的最大值了。
步骤:
1.定义变量,初始化为数组中任意一个元素即可。
2.通过循环语句对数组进行遍历
3.在变量过程中定义判断条件,如果遍历到的元素比变量中的元素大,就赋值给该变量。
需要定义一个功能来完成,以便提高复用性。
1.明确结果,数组中的最大元素int
2.未知内容:一个数组int[]*/
public static void main(String[] args)
{
int[] arr={5,1,4,6,2,8,9};
int max=getMax(arr);
System.out.println("max="+max);
}
public static int getMax(int[] arr)
{
int max=arr[0];
for (int x=1;x<arr.length;x++ )
{
if(arr[x]>max)
max=arr[x];
}
return max;
}
}
2.获取最大值的另一种方式
可不可以将临时变量初始化为0呢?这种方式,其实是在初始化为数组中任意一个角标。
public static void main(String[] args)
{
int[] arr={5,1,4,6,2,8,9};
int max=getMax(arr);
System.out.println("max="+max);
}
public static int getMax(int[] arr)
{
int max=0;
for (int x=1;x<arr.length;x++ )
{
if(arr[x]>arr[max])
max=x;
}
return arr[max];
2.获取最小值
public static void main(String[] args)
{
int[] arr={5,1,4,6,2,8,9};
int min=getMin(arr);
System.out.println("min="+min);
}
public static int getMin(int[] arr)
{
int min=0;
for (int x=1;x<arr.length;x++ )
{
if(arr[x]<arr[min])
min=x;
}
return arr[min];
}
04-数组(排序-选择排序)
对给定数组进行排序{5,1,6,4,2,8,9}
class Sz4
{
public static void main(String[] args)
{
int[] arr=new int[]{3,1,5,6,7};
printArray(arr);//排序前的数组
selectSort(arr);
printArray(arr);//排序后的数组
}
//功能:对数组进行选择排序
选择排序的一个特点:内循环结束一次,最值出现在第一个角标位置上。
public static void selectSort(int[] arr)
{
for (int x=0;x<arr.length-1;x++ )//最后一个角标不用比
{
for (int y=x+1;y<arr.length;y++ )//前后比较
{
if(arr[x]>arr[y])//这是升序排序,降序排序>改为<
{
int temp=arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
}
}
}
//功能:对数组中的元素遍历输出
public static void printArray(int[] arr)
{
for(int x=0;x<arr.length;x++)
{
if(x!=arr.length-1)
System.out.print(arr[x]);
else
System.out.println(arr[x]+"]");
}
}
}
05-数组(排序-冒泡排序)面试当中比较常见的
冒泡排序的一个特点:第一圈结束,最值出现在了最后位。
class Sz5
{
public static void main(String[] args)
{
int[] arr=new int[]{32,1,4,6,25,98};
printArray(arr);//排序前
bubbleSort(arr);
printArray(arr);//排序后
}
//功能:对数组中的元素进行冒泡排序
public static void bubbleSort(int[] arr)
{
for (int x=0;x<arr.length-1;x++ )//最后一个元素不用比较
{
for (int y=0;y<arr.length-x-1;y++ )//-x:让每一次比较的元素减少 -1:避免角标越界
{
if(arr[y]>arr[y+1])//这是升序排序,降序的话改为<
{
int temp=arr[y];
arr[y]=arr[y+1];
arr[y+1]=temp;
}
}
}
}
//功能:对数组中的元素进行遍历输出
public static void printArray(int[] arr)
{
for (int x=0;x<arr.length;x++)
{
if(x!=arr.length-1)
System.out.print(arr[x]+", ");
else
System.out.println(arr[x]);
}
}
}
性能最优的方法:import java.util.*;
Arrays.sort(arr);
真实程序中用这个,但是算法的掌握在面试中是很重要的。
06-数组(排序-位置置换功能抽取)
发现无论什么排序,都需要对满足条件的元素进行位置置换。
所以可以把这部分相同的代码提取出来,单独封装成一个函数。
public static void swap(int[] arr.int a,int b)
{
int temp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}
07-数组(折半查找)
获取这个数在数组中的位置的方法
public static void main(String[] args)
{
int[] arr={4,4,87,23,234};
int index=getIndex(arr,2);
System.out.println("Index="+index);
}
//定义功能,获取key第一次出现在数组中的位置。如果返回是-1,代表该数不存在
public static int getIndex(int[] arr,int key)
{
for (int x=0;x<arr.length;x++)
{
if(arr[x]==key)
return x;
}
return -1;
}
/*折半查找查找速度快,但是有个前提是该数组必须是有序的数组。
最小值min=0 最大值max=arr.length-1 中间值mid=(min+max)/2*/
public static void main(String[] args)
{
int[] arr={2,8,9,10,23,27,32,38,45,52};
int index=halfSearch(arr,32);
System.out.println("Index="+index);
}
//折半的第一种方式
public static int halfSearch(int[] arr,int key)
{
int min,max,mid;
min=0;
max=arr.length-1;
mid=(max+min)/2;
while(arr[mid]!=key)
{
if(key>arr[mid])
min=mid+1;
else if(key<arr[mid])
max=mid-1;
if(min>max)//找不到元素
return -1;
mid=(max+min)/2;
}
return mid;
}
//折半的第二种方式
public static int halfSearch2(int[] arr,int key)
{
int min=0,max=arr.length-1,mid;
while(min<=max)
{
mid=(max+min)>>1;//也是除2
if(key>arr[mid])//key是大值,小角标要变
min=mid+1;
else if(key<arr[mid])
max=mid-1;
else
return mid;
}
return -1;
}
面试题
练习:有一个有序的数组,想要将一个元素插入到数组中,还要保证该数组是有序的。
如何获取该元素在数组中的位置
public static int getIndex_2(int[] arr,int key)
{
int min=0,max=arr.length-1,mid;
while(min<=max)
{
mid=(max+min)>>1;//也是除2
if(key>arr[mid])//key是大值,小角标要变
min=mid+1;
else if(key<arr[mid])
max=mid-1;
else
return mid;
}
return min; //min就是要插入数的具体位置
}
08-数组(十进制---二进制)
//十进制转换为二进制的功能
返回结果是011
public static void main(String[] args)
{
toBin(6);
}
public static void toBin(int num)
{
while (num>0)
{
System.out.println(num%2);
num=num/2;
}
}
但是实际结果是110,所以我们先不打印结果,可以先将数据存储起来(StringBuffer)
该程序返回结果110
public static void main(String[] args)
{
toBin(6);
}
public static void toBin(int num)
{
StringBuffer sb=new StringBuffer();//存储数据的容器
while (num>0)
{
sb.append(num%2);//添加数据
//System.out.println(num%2);先不存起来
num=num/2;
}
System.out.println(sb.reverse());//反转结果
}
08-数组(十进制--十六进制)
60的转换过程:
public static void main(String[] args)
{
toHex(60);
}
//十进制---十六进制
public static void toHex(int num)
{
for(int x=0;x<8;x++)//32位,每次右移4位,最多执行8次
{
int temp=num&15;
if(temp>9)
System.out.println((char)(temp-10+'A'));
else
System.out.println(temp);
num=num>>>4;
}
}
返回结果是C300000
但是实际结果却是3C,这时也要用到反转
public static void main(String[] args)
{
toHex(60);
}
//十进制---十六进制
public static void toHex(int num)
{
StringBuffer sb=new StringBuffer();
for(int x=0;x<8;x++)//32位,每次右移4位,最多执行8次
{
int temp=num&15;
if(temp>9)
//System.out.println((char)(temp-10+'A'));
sb.append((char)(temp-10+'A'));
else
//System.out.println(temp);
sb.append(temp);
num=num>>>4;
}
System.out.print(sb.reverse());
}
10-数组(查表法十进制--十六进制)
//查表法
0 1 2 3 4 5 6 7 8 9 A B C D E F ==十六进制中的元素
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
查表法:将所有的元素临时存储起来,建立对应关系
每一次&15后的值作为索引去查建立好的表,就可以找对应的元素
这样比-10+‘a’简单的多
这个表怎么建立呢?
可以通过数组的形式来定义。
public static void main(String[] args)
{
toHex(60);
}
public static void toHex(int num)
{
char[] chs={'0','1','2','3'//十六进制表中的元素
,'4','5','6','7'
,'8','9','A','B'
,'C','D','E','F'};
for(int x=0;x<8;x++)
{
int temp=num&15;
System.out.println(chs[temp]);
num=num>>>4;
}
}
这样返回结果是C3000000,结果还是反着的
之前用到了StringBuffer这个容器来存储数据,用reverse进行反转,可用来存储数据的容器除了它之外还有数组;
用数组来存储数据要怎么存呢?
public static void main(String[] args)
{
toHex(60);
}
public static void toHex(int num)
{
char[] chs={'0','1','2','3'//十六进制表中的元素
,'4','5','6','7'
,'8','9','A','B'
,'C','D','E','F'};
//定义一个临时容器
char[] arr=new char[8];
/*
for(int x=0;x<8;x++)
{
int temp=num&15;
//System.out.println(chs[temp]);
arr[x]=chs[temp];
num=num>>>4;
}*/
int pos=arr.length;//定义一个指针
while (num!=0)//for是循环8次,而while只对有效位进行循环(输出,,,,,,C,3,)
{
int temp=num&15;
arr[--pos]=chs[temp];
num=num>>>4;
}
System.out.println("pos="+pos);
//存储数据的arr数组遍历(反转输出0,0,0,0,0,0,0,3,C,)
for(int x=pos;x<arr.length;x++)
{
System.out.print(arr[x]+",");
}
}
11-数组(十进制--二进制)
class Sz11
{
public static void main(String[] args)
{
toBin(6);
toBin(-6);
}
public static void toBin(int num)
{
//定义二进制表
char[] chs={'0','1'};
//定义一个临时存储容器
char[] arr=new char[32];
//定义一个操作数组的指针
int pos=arr.length;
while(num!=0)//对有效位进行循环操作
{
int temp=num&1;//二进制&1位
arr[--pos]=chs[temp];//倒序存入数组中
num=num>>>1;
}
for(int x=pos;x<arr.length;x++)//从有效位开始遍历
{
System.out.print(arr[x]);
}
}
}
这种十进制到二进制的转换方法是正负数通用的。
但是不难发现,不管转换成十六进制还是二进制,定义的数组中都包含'0','1'两个元素,进行的操作中都有定义容器,操作方式也是一样的。
不同的数是&的数不一样,右移的位数不一样,操作数不一样,我们可以将共性操作提取出来,进行优化代码
class Sz12
{
public static void main(String[] args)
{
toBin(6);
toBin(-6);
toHex(60);
}
//十进制---二进制
public static void toBin(int num)
{
trans(num,1,1);
}
//十进制---八进制
public static void toOct(int num)
{
trans(num,7,3);
}
//十进制---十六进制
public static void toHex(int num)
{
trans(num,15,4);
}
public static void trans(int num,int base,int offset)//操作数、基数、右移位数
{
if(num==0)
{
System.out.println(0);
return;
}
char[] chs={'0','1','2','3'//十六进制表中的元素
,'4','5','6','7'
,'8','9','A','B'
,'C','D','E','F'};
//定义一个临时存储容器
char[] arr=new char[32];
//定义一个操作数组的指针
int pos=arr.length;
while(num!=0)
{
int temp=num&base;
arr[--pos]=chs[temp];
num=num>>>offset;
}
for (int x=pos;x<arr.length;x++ )
{
System.out.print(arr[x]);
}
}
}
13-数组(二维数组)
class Sz13
{
public static void main(String[] args)
{
int[] arr1=new int[3];//一维数组
int[][] arr2=new int[3][4];//定义了名称为arr2的二维数组,二维数组中有3个一维数组
// 每一个一维数组中有四个元素
System.out.println(arr[0]);//返回0000,第一个一维数组
int[][] arr=new int [3][];//3个二维数组
arr[0]=new int[3];
arr[1]=new int[1];
arr[2]=new int[2];
System.out.println(arr[0]);//返回null
System.out.println(arr.length);//打印二维数组的长度3
System.out.println(arr[0].length);//打印二维数组中第一个一维数组长度
int[][] arr={{3,2,1},{3,5,2},{1,4,6}};
公司有3个销售组
{{},{},{}}
获取公司的总销售额
for(int x=0;x<arr.length;x++)
{
for (int y=0;y<arr[x].length;y++)
{
sum=sum+arr[x][y];
}
}
System.out.println("sum="+sum);
}
}
14-数组(二维数组练习)
注意二维数组的写法
int[] x; intx[];一维数组
int[][]y; inty[][]; int[] y[];二维数组
//判断下列选项的对与错
int[] x,y[];
/*分析题目:
x一维数组 y二维数组
int[] x;
int[] y[];
*/
a.x[0]=y;错
b.y[0]=x;对
c.y[0][0]=x;错
d.x[0][0]=y;错
e.y[0][0]=x[0];对
f.x=y;错