2.Java语言基础
Java语言基础组成:关键字、标识符、注释、常量与变量、运算符、语句、函数、数组。
2.1 关键字
什么是关键字:就是被赋予了Java特殊含义的单词。(都是小写)
如:class、public、synchronized、static等等,比较多,不一一列举,不需要刻意去记忆关键字。
2.2 标识符
什么是标识符:就是程序中自定义的一些名称。如:类名、方法名都是标识符。
标识符的组成:26个英文字母大小写(Java中严格区分大小写)、0-9数字、以及$符号、_下划线。
注意:1、标识符不能以数字开头。2、不能使用关键字作为标识符。
合法标识符:method、demo、Abc_123、$abc。
非法标识符:123ABC、My Demo、@Abc。
Java语言有其自己的一些规范:
如:程序中的类名每个单词首字母都要大写
class Demo{}、class DemoTest{}。
程序中的方法名第一个单词小写,后面每个单词首字母都要大写。
public void method(){}
public int getMax(){}。
2.3注释
什么是注释:就是用于注解说明的文字。
注意:注释除了注解说明程序的作用,还有一个作用就是可以调试程序,缩小程序的问题范围。
Java中的注释分为:单行注释 符号:“ \\注释内容”
多行注释 符号:“ /*…….注释内容………*/”
文档注释 符号:“/**…….注释内容………/*”(文档注释,可以通过javadoc命令,将文档注释信息转成html页面。)
/**
需求:编写一个程序,在控制台输出:Hello World!
思路:1,java程序的编写是以类的形式体现的,类是存储代码的地方。
2,有了类,还要有程序的入口,那就是主函数。
3,要在控制台输出信息,就需要写输出语句。
步骤:1,定义一个类,类名为Demo
2,写主函数,这是JVM所能识别的固定格式。
3,写输出语句,输出Hello World信息,到控制台。
*/
public class Demo //定义一个类名为Demo 的类。
{
public static void main(String[] args) //编写主函数。
{
System.out.println("Hello World!"); //写输出语句,输出Hello world信息。
}
}
2.4 常量与变量
常量:表示不能改变的数值.
Java中常量的分类:
1, 整数常量:所有整数。
2, 小数常量:所有小数。
3, 布尔常量:true、false。
4, 字符常量:将一个字母、数字或符号用单引号‘’标识。
5, 字符串常量:将一个或多个字符用双引号“”标识。
6, null常量:null
整数的四种表现形式:
1, 二进制:0、1。
2, 八进制:0-7,0开头。
3, 十进制:0-9。
4, 十六进制:0-9,A-F,0x开头。
进制的互转:
1,十进制转二进制(就是用十进制数去除以2,再用商除以二,直到不能整除。记录每次得到的余数,就是二进制位。)
如:十进制数10,转二进制
10转成二进制为:1010.
Java中整数类型默认为int型,占4个字节,32位。
整数10 的二进制位就是:0000-0000 0000-0000 0000-0000 0000-1010
由此得出结论:10进制数转八进制数就是除以8,取余数。10进制转16进制就除以16,取余数。但要注意为了让8进制数和16进制数区分开,8进制数开头加0,16进制数开头加0x。
如:八进制:056 、067.
十六进制:0xAE、0x89.
1, 二进制转十进制、八进制、十六进制。
如:十进制数:345
可以写成:5*10(0)+4*10(1)+3*10(2)
那么,二进制位:0000-0000 0000-0000 0000-0000 0000-1110可以写成:
0*2(0)+1*2(1)+1*2(2)+1*2(3)+0*2(4)+…….+0*(31)=14.
(这里我只计算有效位1,其他为0的就不计算)。
我们知道:八进制的中每一位的最大值是7,十六进制的每一位最大值是15也就是(F)。因为二进制中3个二进制位能表示的最大数是7,4个二进制位能表示的最大数是15.
由此得出结论:八进制数实际上就是二进制位中3个二进制位,为一个八进制位。
十六进制实际上就是二进制位中4个二进制位,为一个十六进制位。
如: 110 010 010转八进制数(按每3位进行计算):0622
1100 0110 转十六进制数(按4位进行计算):0xC6
变量:内存中的一个存储区域。
该区域有自己的名称(变量名)和类型(数据类型)该区域的数据可以在同一类型范围内不断变化。
为什么要定义变量?
因为变量的值是不固定的,同一区域中可以用来不断存放同一类型的常量。
什么时候定义变量?
当数据不确定时。
使用变量要注意:变量的作用范围(一对{}之间)和变量的初始化值。
格 式:数据类型 变量名=初始化值。
Java中变量的类型:
byte占一个字节、short占两个字节、int占四个字节、long占八个字节、float占四个字节、double占八个字节、char占两个字节、boolean占一个二进制位。
为了区分long和int,float和double,定义的long型变量后面加l,定义的float型后加f。
整数默认为int型。
小数默认为double型。
2.4.1自动类型提升和强制类型转换。
自动类型提升是隐式类型转换。
强制类型转换是显示类型转换。
表达式的数据类型自动提升:
所有byte、short、char型值将被提升为int型。
如果一个操作数是long型,运算结果就是long型。
如果一个操作数是float型,运算结果就是float型。
如果一个操作数是double型,运算结果就是double型。
分析:int x=3;
x=x+5;
的内存原理:
自动类型提升
如: int x=3;
byte b=5;
x=x+b;
x=x+b;x占四个字节,b占一个字节;运算中b会自动提升为int型。
所以:x=8,这里要注意的是,x+b的值,不能超过x的取值范围。否则数值就会出错。
强制类型转换
如:
byte b=3;
b=b+4;
b在运算中默认提升为int型,4默认为int型。
因为b占一个字节,而b+4的结果是int型,这里就会报错,所以必须进行强制类型转换;改为
b=(byte)(b+4);就可以了。结果为:7.
那么为什么强转后,还能输出正确结果呢?
因为,被强转为byte后,b+4的值依然在byte取值范围内。那么如果b+4的值大于byte的取值范围,就会产生问题。
所以,强转要慎用!
如:b=(byte)(b+128);输出结果是个负数,是因为只保留了运算结果的最低8位,也就是一个字节。
字符类型的运算过程:
System.out.println(‘a’);和System.out.println(‘a’+1);的区别?
这里System.out.println(‘a’); 输出字母a。
而 System.out.println(‘a’+1);输出数字98.原因是因为‘a’+1,表达式中的‘a’,会自动提升为int型,又因为,‘a’在ASCII码表的对应数字是97,所以,输出运算结果98.
类型运算细节
如:
A: byte b=4;
b=3+7;
System.out.println(b); //结果:10
而
B: byte b1=3;
byte b2=7;
b=b1+b2;
System.out.println(b);//这里就会报错:丢失精度。
那么,区别在哪呢?
在A 中,整数默认为int型,4在byte类型的取值范围类,编译器进行了强转,b=3+7,也是同样的道理。
在B中,b=b1+b2,因为b1和b2是两个变量,他们的值是不确定的,检查不通过,就会报错。
总结:如果表达式右边的确定值,且在byte取值范围内,编译通过。
如果表达式右边的不是确定值,编译报错,除非进行强转(byte b=(byte)(b1+b2))。
2.5 运算符
Java中的运算符包括:算术运算符、自增自减运算、赋值运算符、比较运算符、逻辑运算符、位运算符、三元运算符。
2.5.1 算术运算符
包括:+(加法)、-(减法)、*(乘法)、/(除法)、%(模运算,取余数)
+号的两种作用:1,加法运算符 2,连接符
任何数和字符串用+号相连,形成一个更大的字符串。如:System.out.println(3+“a”);就是:3a。
Java的加减乘除运算与数学中的一样。
%(模运算,取余数),也就是取余数运算。
如:System.out.println(5%2);//结果为:1.
System.out.println(4%2);//结果为:0.
System.out.println(2%5);//结果为:2.
总结:模运算,左边>右边,结果为运算的余数。
左边<右边,结果为左边。
左边=右边,结果为0.。
有符号的模运算,如:
System.out.println(-5%2);//结果为:-1;
System.out.println(5%-2);//结果为:1;
总结:有符号的模运算,余数的符号,只取决于左边的数。
2.5.2 自增自减运算
++(自增运算)、--(自减运算)。
自增运算:就是在原有数据基础上加1。
自减运算:就是在原有数据基础上减1.
如:int a=3;
a++;
System.out.println(a);//结果为:4.
自增自减在某些情况,会有所不同。
如: int a=3,b;
b=a++;
System.out.println("a="+a+",b="+b);//结果:a=4,b=3;
而: int a=3,b;
b=++a;
System.out.println("a="+a+",b="+b);//结果:a=4,b=4;
为什么?
b=a++,原理图:在内存中,先临时存储变量a的值,再
将a的值进行加1运算,运算的结果,再赋给a,原来的
值3被运算结果4覆盖,然后,再将临时存储的值3
赋给变量b。所以,a=4,b=3.
b=++a,原理图:在内存中,先进行a的值加1运算,然
后,再把变量a的值赋给变量b。
所以,a=4,b=4.
2.5.3 赋值运算符
包括:=、+=、-=、*=、/=、%=。
如: int a=3;
a+=1,相当于:a=a+1;
a-=1,相当于:a=a-1;
a*=1,相当于:a=a*1;
a/=1, 相当于:a=a/1;
a%=1,相当于:a=a%1;
注意:在某些情况下,a+=1,和a=a+1,是有区别的。
如:
byte a=3;
a+=1;结果a的值是4。
a=a+1; 报错。
为什么呢?
整数默认是int类型,因为在编译过程中,a=a+1,a是变量,值不确定,会丢失精度;而a+=1,只要运算结果不超出byte取值范围,底层有一个强转的动作。a+=1,就相当于:a=(byte)(a+1);所以编译通过,并运算出结果。
2.5.4 比较运算符
包括:>(大于)、<(小于)、>=(大于等于)、<=(小于等于)、!=(不等于)、==(等于)、instanceof(如 a instanceof b 判断a是否是b类的对象)
比较运算符的运算结果,只能是boolean类型:true or false
如:
class Demo {
public static void main(String []args){
int a=3,b=4;
if(a>b)
System.out.println(“a=”+a);
System.out.println(“b=”+b);
}
}
注意:比较运算符==与赋值运算符=,是两个不同的运算符,==判断左右两边是否相等,=是将右边的值,赋给左边。
2.5.5 逻辑运算符
包括:&(与)、|(或)、!(非)、&&(短路与)、||(短路或)、∧(异或)。
&运算特点:
true & false=false
false & true=false
true & true=true
false & false=false
&运算规律:&运算的两边只要有一个为false,结果就是false;只有两边都为true,结果才是true。
|运算特点:
true | false =true
false | true =true
true | true =true
false | false=false
|运算规律:|运算的两边只要有一个为true,结果就是true;只有两边都是false,结果才是false。
∧异或运算特点:
true ∧ false =true
false ∧ true=true
true ∧ true=false
false ∧ false=false
∧运算规律:∧运算的两边只要相同,结果就是false;两边不同,结果是true。
!非运算
就是取相反的一面,如:!true=false、!false=true。
&&运算
&&运算和&运算的运算结果相同,但是两者有区别:
&运算,不管左边是true还是false,右边都参与运算;&&运算,如果左边为true时,右边参与运算,如果左边为false时,右边不参与运算。因为&运算的结果,只要有一个为false,结果就是false,所以,&&运算比&运算要高效,一般都用&&运算。
||运算
||运算和|运算的运算结果相同,但是两者有区别:
|运算,不管左边是true还是false,右边都参与运算;||运算,如果左边为false时,右边参与运算,如果左边为true时,右边不参与运算。因为|运算的结果,只要有一个为true,结果就是true,所以,||运算比|运算要高效,一般都用||运算。
2.5.6 位运算符
位运算符的概念:二进制位的运算符号。
整数有几种表现形式,其中一种就是二进制,一个int类型整数占四个字节,每个字节是8位,那么就是32位,位运算符,就是对这些二进制位进行运算的符号。
位运算符包括:〈〈(左移)、〉〉(右移)、〉〉〉(无符号右移)、 &(与)、|(或)、 ∧(异或)、 ~(反码)。
〈〈左移运算符:
如:整数3左移2位: 3〈〈2 结果是:12 如图:
由此可见:3〈〈2相当于 3*2(2)=3*4=12
注意:左移时,移除的高位丢弃,空位补0。
左移运算规律:一个数左移几位,就相当于这个数乘以2的几次方。
如:3 〈〈3 相当于:3*2(3)=24.
〉〉右移运算符
如:整数6右移2位:6〉〉2 结果:1 如图:
由此可见:6〉〉2 相当于6/2(2)=6/4=1
注意:右移时,高位是0的,补0;是1,就补1.
右移运算规律:一个数右移几位,就相当于这个数除以2的几次方。
〉〉〉无符号右移运算符
无符号右移与右移基本差不多,只是无论高位是0,还是1,都用0补。
&运算符:就是把二进制位进行与运算。
如:6&2=2
|运算符:就是把二进制位进行或运算。
如:6|2=6
∧运算符:就是把二进制位进行异或运算。
如:6^2=4
注意:一个数异或另一个数两次,结果还是这个数。
如:a^b^b=a
使用异或运算,可以完成数值的交换(不使用第三方变量)。
如:int a=3,b=4;
a=a^b;
b=a^b;
a=a^b;
结果:a=4,b=3。
~运算符:就是把一个数的二进制位取反,1就是0,0就是1.
如:~6=-7,~ -6=5.
个人总结:正数的反码,结果是比这个数大1的负数。
负数的反码,结果是比这个数小1的正数。
注意:负数的二进制位是正数的二进制位取反再加1.
2.5.7 三元运算符
三元运算符概念:三个元素参与运算的符号.
一个元素参与运算的符号是一元运算符.如:++,――等。
二个元素参与运算的符号是二元运算符.如:+、-、*、/、%等。
格式:
(条件表达式)?表达式1:表达式2
如果,条件表达式结果为true,结果是表达式1.
如果,条件表达式结果为false,结果是表达式2.
如:
int a=3,b=4;
int c=(a>b)?a:b;
int d=(a<b)?a:b;
System.out.println(c);//条件表达式为false,结果是4.
System.out.println(d);//条件表达式为true,结果是3.
2.6 语句
Java中的语句按照程序的流程控制分为三种结构:判断结构、选择结构、循环结构。
2.6.1 判断结构
语句格式:
1, if(条件表达式){
…执行语句….
}
if语句,只要条件表达式结果为true,就执行其内部语句;如果为false就不执行。
2, if(条件表达式){
…执行语句…. }
else{
…执行语句….
}
if…..else语句,如果条件表达式结果为true,就执行if的内部语句,如果条件表达式结果为false,则执行else的内部语句。
3,if(条件表达式){
…执行语句….
}else if(条件表达式){
…执行语句….
}else if(条件表达式){
…执行语句….
}……
else{
}
if…..else if……else if…..else语句,可以对多个条件表达式进行依次判断,哪一个结果为true,就执行其内部语句,如果所有条件表达式结果都是false,则执行else中的语句。
注意:判断结构的语句,一次只能执行其中一个语句。
2.6.2 选择结构
switch语句
格式:
switch(表达式)//表达式允许四种类型:byte、short、int、char(jdk1.7增加的String类型)
{
case 取值1:执行语句;
break;
case 取值2:执行语句;
break;
case 取值3:执行语句;
break;
…...
default:执行语句;
break; }
switc语句,会根据表达式,去选择与其匹配的值,从第一个case开始,依次查找,如果找到,就执行对应的case的语句,然后由break,结束switch语句。如果,所有case中都没有找到匹配的值,就执行default的语句,然后,结束switch语句,default也可以不写。
注意:
1,switch语句中,如果找到与表达式匹配的值,就会执行对应case:后的语句,依次执行,直到遇到break或“}”括号。所以,break在switch显得比较重要。
如:
public class Demo
{
public static void main(String args[]){
int x=3;
switch(x){
case 1:x+=1;
break;
case 2:x+=2;
break;
case 3:x+=3;//后面没有break,执行x+=3后,继续执行x+=4,然后,结束switch语句.
case 4:x+=4;
break;
default:System.out.println("没有匹配数字");
}
System.out.println("x="+x);//结果为10;
}
}
2,switch中,多个case可以对应一个执行语句。
如:
switch(表达式){
case 1:
case 2:
……
执行语句;
break;
case 3:
case 4:
……
执行语句;
break;
……..
default:执行语句;
}
2.6.3 循环结构
1,for(初始化表达式;循环条件表达式;循环后的操作表达式){循环体;}
for循环的执行顺序:①初始化表达式②循环条件表达式③循环体④循环后的条件表达式,如果依然符合循环条件表达式,则继续循环执行循环体,否则循环结束。
如果for循环中没有任何表达式,就是无限循环。
如;for(;;){循环体;}
for循环的嵌套:就是大圈套小圈的思想,在某种情况下,当一次对应另一种情况的多次时,就可以使用for嵌套。
如:打印一个由“*”号组成的矩形。
public class Demo
{
public static void main(String args[]){
for(int x=1;x<=5;x++){
for(int y=1;y<=5;y++){
System.out.print("*");
}
System.out.println();
}
}
}
/*打印图形:
*****
*****
*****
*****
*****
*/
2 ,do{
循环体;
}
while(循环条件表达式);
do while循环语句:会先执行一次循环体,再判断循环条件。所以,无论是否满足条件,循环体都至少执行一次。
如:
public class Demo
{
public static void main(String args[]){
int x=1;
do{
System.out.println("打印"+x+"次");
x++;
}while(false);
}
}
while的循环条件为false,所以只显示一次。
控制台显示:打印1次。
3,while(循环条件表达式){
循环体;
}
while循环语句:首先判断是否满足循环条件,满足就执行循环体,否则不执行。while循环当循环体每次执行后,都会再判断是否满足循环条件,如果不满足就结束循环。
如果while循环条件是true,就是无限循环。
while(true){循环体;}
while循环实现累加算法:
如:计算数字1-100的和。
public class Demo
{
public static void main(String args[]){
int x=1;
int sum=0;
while(x<=100){
sum+=x;//从1开始每次相加的结果,与下一个数再相加,直到100。
x++;
}
System.out.println("数字1到100的和="+sum);
}
}
while循环的计数器思想:
如:1-100中6的倍数的个数。
public class Demo
{
public static void main(String args[]){
int x=1;
int count=0;//定义一个变量作为计数器
while(x<=100){
if(x%6==0){//通过if条件来判断1-100中6的倍数。
count++;//只要一个数模于6的结果是0,count就自增一次,进行计数。
}
x++;
}
System.out.println("6的倍数的个数="+count);
}
}
什么时候使用循环?
当某些代码需要运行很多次时。
if和while的区别?
if:只判断条件一次,就不再判断。
while:每次循环结束后,都会再判断是否满足循环条件,会多次判断条件。
for和while的区别?
for和while可以互换。
for循环中定义的变量,循环结束后,变量就释放了。
while循环定义的变量,循环结束后,依然可以使用。
使用循环是要注意什么?
1,代码中哪些需要循环,哪些不需要循环。
2,定义循环的条件和控制循环的次数。
循环语句中两个重要的关键字:break、continue
break和continue有什么不同?
break:终止所在的当前循环,或终止指定的循环(前提是给嵌套循环加上标签)。
continue:终止所在的当前循环的本次循环,继续下一次循环;或继续指定的循环(前提是给嵌套循环加上标签)。
break不仅可以在循环语句中使用,还可以在选择语句中使用,如:switch语句。而continue只能在循环语句中使用。
注意:break和continue下面不能有其他语句,因为执行不到,所以编译时会报错,除非是有条件控制的。
如:
public class Demo
{
public static void main(String args[]){
for(int x=1;x<=5;x++){
for(int y=1;y<=x;y++){
System.out.print("*");
break;
System.out.print(x);// 编译时报错:无法访问的语句。
}
System.out.println();
}
}
}
如果,用if来控制,就可以。
public class Demo
{
public static void main(String args[]){
for(int x=1;x<=5;x++){
for(int y=1;y<=x;y++){
System.out.print("*");
if(x==1)
break;
System.out.print(x);
}
System.out.println();
}
}
}
编译通过。
2.7 函数
函数的概念:定义在类中,具备特定功能的小程序,就是功能代码的封装体。函数也称为方法。
函数定义的格式:
修饰符 返回值类型 函数名(参数列表……){
功能代码;
return 返回值;
}
如:
public static int add(int x,int y){
int sum=0;
sum=x+y;
return sum;
}
定义函数要注意:
1,如果函数没有具体返回值,这时函数的返回值类型就不能用具体的类型来表示,则使用关键字void表示,return语句后用“;”号结束,也可以不写return语句。
如:
public static void print(){
System.out.println(“Hello world!”);
return;//此语句可以省略不写。
}
2,函数是定义在类中的,函数中只能调用函数,不能定义函数。
public class Demo
{
public static void main(String args[]){//主函数
int sum=add(2,3);//调用自定义函数,并把add方法运算结果赋值给sum变量。
System.out.println(sum);//打印sum变量的值。
}
public static int add(int x,int y){//自定义函数
return x+y;
}
}
3, 函数的返回值应该返回给调用者,由调用者处理。
函数的特点:
1, 函数是将功能代码进行封装。
2, 方便对该功能的复用。
3, 函数只有在被调用时才会执行。
4, 函数的出现提高了代码的复用性。
5, 对于没有具体返回值的函数,函数的返回值类型用void表示,return语句可以省略不写。
函数定义的两个明确:
1, 函数的返回结果是什么?
2, 是否有未知内容参与运算。
函数的特性重载(overload)
什么是重载?
在一个类中,有一个以上的同名函数,且具有不同的参数个数或不同的参数类型。(注意:当所有的参数都是相同类型事,不考虑参数顺序;但是,如果所有参数类型不是相同类型时,要考虑到参数的顺序)
总结函数重载的条件:
1, 同一个类中。
2, 相同的方法名。
3, 不同的参数个数,不同的参数类型,不同的参数顺序。
4, 函数的重载与返回值类型无关。
如:
/*
Demo类中,add方法重载,他们有相同的方法名不同的参数个数、参数类型、参数顺序。
*/
public class Demo
{
public static void main(String args[]){
int a=add(1,2);
int b=add(1,2,3);
double c=add(1.3,2);
double d=add(2,1.3);
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println("c="+c);
System.out.println("d="+d);
}
public static int add(int x,int y){//两个int类型参数。
return x+y;
}
public static int add(int x,int y,int z){//三个int类型参数。
return x+y+z;
}
public static double add(double x,int y){//与下面的add方法有相同的参数,但参数的排列顺序不同。
return x+y;
}
public static double add(int x,double y){
return x+y;
}
}
2.8 数组
什么是数组?
数组就是同一种数据类型的集合,数组也称为容器。
使用数组的好处:数组中存储的元素,会从0开始自动编号,方便对这些元素的操作。
数组定义的格式:
如: int []arr=new int[3];//明确数组的长度。
int []arr=new int[]{1,2,3};//明确数组中的元素。
int []arr={1,2,3};//明确数组中的元素。
注意:数组一旦定义,就要明确长度或数组中的元素,否则,编译失败。
如:
public class Demo
{
public static void main(String args[]){
int []arr=new int[];//编译时报错:缺少数组维数
}
}
桟内存:内存中的一片存储区域,用来存储局部变量。
释放方式:作用域一旦结束,局部变量就自动释放。
堆内存:也是内存中的一片存储区域,用来存储实体,如:数组、对象(数组就是对象)。凡是用new关键字建立的,都存储在堆内存中。
堆内存的特点:
1,堆内存中的每一个实体都有一个首地址值.
2,堆内存中的变量,默认都有一个初始化值,根据类型的不同而不同,如:byte、short、int、long都是0,char是‘\u0000’,
boolean是false、double或float是0.0或0.0f、引用类型是null。
3, 释放方式:JVM的垃圾回收机制。
数组创建时内存中的原理图:
遍历数组:
public class Demo
{
publicstatic void main(String args[]){
int[]arr=new int[3];
for(intx=0;x<arr.length;x++){
System.out.println("arr["+x+"]="+arr[x]);
}
}
多个引用型变量指向同一个数组实体:
如:
public class Demo
{
publicstatic void main(String args[]){
int[]arr_1=new int[3];
int[]arr_2=new int[3];
arr_1[0]=9;
arr_2[2]=34;
arr_1=arr_2;
for(intx=0;x<arr_1.length;x++){
System.out.println("arr_1["+x+"]="+arr_1[x]);
}
}
/*
显示结果:
arr_1[0]=0
arr_1[1]=0
arr_1[2]=34
*/
如图:
总结:arr_1=arr_2,就是将arr_2的地址值,赋给arr_1变量,这样arr_1就会指向新的数组实体,实际上就是两个引用型变量arr_1和arr_2,都指向了同一个数组实体,那么arr_1之前指向的实体就是垃圾。所以在遍历arr_1数组时,就是等于在遍历arr_2数组。
总结数组中常见问题:
1, 在数组中对元素的操作,是通过元素的角标来完成的,对元素的存取和其他操作,但是如果用到的角标超出了数组中的角标范围,就会有异常情况发生:ArrayIndexOutOfBoundsException(角标越界异常)。但是,编译是可以通过的,运行时就会报错。
如:
public class Demo
{
publicstatic void main(String args[]){
int[]arr=new int[3];
arr[3]=4;
System.out.println(arr[3]);
}
}
数组的最小角标是0,最大角标是数组的长度-1,就是:数组名.length-1,一旦超出范围就会报此错误。
2, 当数组引用型变量,没有指向数组实体时,还在用这个变量来操作实体,就会发生该异常:NullPointerException(空指针异常)。编译是可以通过的,运行时就会报错。
3,
如:
public class Demo
{
publicstatic void main(String args[]){
int[]arr=null;
arr[3]=4;
System.out.println(arr[3]);
}
}
数组的常见操作:
1, 自定义函数实现数组中元素的位置互换。
public class Demo
{
publicstatic void main(String args[]){
int[]arr={2,3,4,67,89,100,23};
printArray(arr);
reverseArray(arr);
printArray(arr);
}
publicstatic void reverseArray(int []arr){//自定义函数实现数组中元素的反转。
intstart=0;
intend=arr.length-1;
while(start<end){
swap(arr,start,end);//调用自定义函数互换元素的位置
start++;
end--;
}
}
publicstatic void swap(int []arr,int a,int b){//自定义函数实现数组中元素的位置交换。
inttemp=arr[a];//使用第三方变量,完成元素的互换
arr[a]=arr[b];
arr[b]=temp;
}
publicstatic void printArray(int []arr){//自定义函数遍历数组。
System.out.print("[");
for(intx=0;x<arr.length;x++){
if(x!=arr.length-1)
System.out.print(arr[x]+",");
else
System.out.println(arr[x]+"]");
}
}
}
/*
显示结果:
[2,3,4,67,89,100,23]
[23,100,89,67,4,3,2]
*/
2, 二分查找
/*通过给定的元素,在数组中查找到对应的角标,找不到就返回-1*/
public class Demo
{
publicstatic void main(String args[]){
int[]arr={2,3,4,67,89,100,23};
intindex=halfSearch(arr,22);
System.out.println("index="+index);
}
publicstatic int halfSearch(int []arr,int key){//定义函数折半查找指定key的角标
intmin=0;
intmax=arr.length-1;
intmid=(min+max)/2;
while(arr[mid]!=key){
if(arr[mid]>key)
max=mid-1;
if(arr[mid]<key)
min=mid+1;
if(max<min)
return-1;
mid=(min+max)/2;
}
returnmid;
}
}
3, 数组查表法
/*通过输入数字,获取对应的星期*/
public class Demo
{
publicstatic void main(String args[]){
System.out.println(getWeek(6));
}
publicstatic String getWeek(int num){
if(num>7||num<1)
System.out.println("没有匹配的星期");
String[]weeks={"星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
returnweeks[num];
}
}
4, 排序
/*选择排序*/
public class Demo
{
publicstatic void main(String args[]){
int[]arr={2,45,6,34,76,88,123,46,89,100};
printArray(arr);
selectSort(arr);
printArray(arr);
}
publicstatic void selectSort(int []arr){//定义函数实现选择排序功能。
for(intx=0;x<arr.length-1;x++){
for(inty=x+1;y<arr.length;y++){
if(arr[x]>arr[y])
swap(arr,x,y);
}
}
}
publicstatic void swap(int []arr,int a,int b){//定义函数实现数组中元素的位置交换。
inttemp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}
publicstatic void printArray(int []arr){//定义函数遍历数组中的元素。
System.out.print("[");
for(intx=0;x<arr.length;x++){
if(x!=arr.length-1)
System.out.print(arr[x]+",");
else
System.out.println(arr[x]+"]");
}
}
}
/*
排序前:[2,45,6,34,76,88,123,46,89,100]
排序后:[2,6,34,45,46,76,88,89,100,123]
*/
/*冒泡排序*/
public class Demo
{
publicstatic void main(String args[]){
int[]arr={2,45,6,34,76,88,123,46,89,100};
printArray(arr);
bubbleSort(arr);
printArray(arr);
}
publicstatic void bubbleSort(int []arr){//定义函数实现冒泡排序
for(intx=0;x<arr.length-1;x++){
for(inty=0;y<arr.length-1-x;y++){
if(arr[y]>arr[y+1])
swap(arr,y,y+1);
}
}
}
publicstatic void swap(int []arr,int a,int b){//定义函数实现数组中元素的位置互换
inttemp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}
publicstatic void printArray(int []arr){//定义函数遍历数组
System.out.print("[");
for(intx=0;x<arr.length;x++){
if(x!=arr.length-1)
System.out.print(arr[x]+",");
else
System.out.println(arr[x]+"]");
}
}
}
/*
排序前:[2,45,6,34,76,88,123,46,89,100]
排序后:[2,6,34,45,46,76,88,89,100,123]
*/
2.8.2 二维数组
格式:
元素类型 [ ] [ ]数组名=new 元素类型 [一维数组个数] [一维数组的长度];
元素类型 [ ] [ ]数组名=new 元素类型 [一维数组个数] [ ];
元素类型 [ ] [ ]数组名={{指定元素},{指定元素},{指定元素}……};
总结二维数组的创建要明确的条件:
1, 明确二维数组中一维数组的个数和一维数组的长度。
2, 只明确二维数组中一维数组的个数。
3, 明确二维数组中一维数组个数和指定元素。
4, 二维数组创建时,必须要明确一维数组的个数或指定一位数组中的元素,否则编译失败。
如:
public class Demo
{
publicstatic void main(String args[]){
int[][]x=new int[3][2];
int[][]y=new int[3][];
int[][]z={{2,45,6,34},{76,88,123},{46,89,100}};
}
}
二维数组创建内存原理图:
二维数组的遍历:
一维数组遍历用到for循环,二维数组的遍历需要for循环的嵌套。
public class Demo
{
publicstatic void main(String args[]){
int[][]arr={{2,45,6,34},{76,88,123},{46,89,100}};
for(intx=0;x<arr.length;x++){//外循环遍历一维数组。
for(inty=0;y<arr[x].length;y++){//内循环遍历一维数中的元素。
System.out.println(arr[x][y]);
}
}
}
}
二维数组什么时候用?
数组时用来存储数据的,数据多了就可以用数组存,那么如果数组多了,就可以使用二维数组来存储,数组的维数是不固定的,甚至还有更多维数的数组。
总结:数组是一个容器,用于存储数据的,对数组中的元素进行操作,就需要用到数组中元素对应的角标,操作数组中元素的角标是要注意:角标越界和空指针两个异常的发生。数组的创建要明确哪些是必须的条件,否则编译失败。数组中的元素类型必须是相同的。
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net