------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、常见的DOS命令
1 cd---------进入指定目录 2 cd.. -------退出到上级目录 3 cd\--------退出到根目录 4 md----------创建文件夹 5 rd--------------删除文件夹 6 del-----------删除文件 7 dir--------列出当前目录下的文件和文件夹 8 exit------退出dos命令行
二、java注意的地方
每一个java源文件中可以定义多个java类(class类),这么多的类中必须有一个可以jvm入口的main函数。其中每一个java源文件最多只能有一个类被定义成public类,若源文件中包括了public类,源文件名必须和该public类名一样。一个源文件中包含N个Java类时,编译后会生成N份字节码文件,即每个类都会生成一份单独的class文件,且字节码文件名和其对应的类名相同。
多行注释(/* */)和文档注释(/** */)都不能嵌套使用。
三、关键字和标识符
(1)、关键字:被Java语言赋予了特殊含义的单词,关键字中所有字母都为小写。
java部分关键字罗列:
注:main不是关键字,是被虚拟机所识别的一个名称。
(2)、标识符
标识符:在程序中自定义的一些名称。由26个英文字母大小写,数字:0-9,符号:_、$组成。
标识符规则:
1.由26个英文字母大小写、0-9数字、_和$符号组成
2.数字不可以开头
3.不可以使用关键字
Java中严格区分大小写。在起名字的时,为了提高阅读性,要尽量有意义。
Java中的名称规范:
包名:多单词组成时所有字母都小写。
eg: xxxyyyzzz
类名接口名:多单词组成时,所有单词的首字母大写。
eg:XxxYyyZzz
变量名和函数名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写。
eg:xxxYyyZzz
常量名:所有字母都大写。多单词时每个单词用下划线连接。
eg:XXX_YYY_ZZZ
四、常量和变量
(1)、常量
常量表示不能改变的数值。
Java中常量的分类:
1. 整数常量:所有整数。
2. 小数常量:所有小数。
3. 布尔(boolean)型常量:只有两个数值,true、false。
4. 字符常量:将一个数字字母或者符号用单引号( ‘ ‘ )标识,如:‘a‘。
5. 字符串常量:将一个或者多个字符用双引号("")标识,如:"hello world"、"a"、""(空字符串)。
6. null常量:只有一个数值就是:null。
(2)、变量
变量:其实就是内存中的一个存储空间,用于存储常量数据。
作用:方便于运算。因为有些数据不确定。所以确定该数据的名词和存储空间。
特点:变量空间可以重复使用。
什么时候定义变量?只要是数据不确定的时候,就定义变量。
定义变量的格式:
数据类型 变量名 = 初始化值;
例如:int x= 3;
变量空间的开辟需要什么要素呢?
1.这个空间要存储什么数据?数据类型。
2.这个空间叫什么名字啊?变量名称。
3.这个空间的第一次的数据是什么? 变量的初始化值。
变量的作用域和生存期:
变量的作用域:
作用域从变量定义的位置开始,到该变量所在的那对大括号结束;
生命周期:
变量从定义的位置开始就在内存中活了;变量到达它所在的作用域的时候就在内存中消失了。
五、进制和进制之间的转换
(1)、进制
对于整数:java有三种表现形式。
十进制:0-9 ,满10进1.
八进制:0-7 ,满8进1. 用0开头表示。
十六进制:0-9,A-F,满16进1. 用0x开头表示。
规律:进制越大,表现形式越短。
注意的是为了区分八进制、十进制和十六进制的表现形式,所以八进制用0开头表示,如:012;十六进制用0x开头表示,如:0x4a8c。
八进制用3个二进制表示一位,十六进制用4个二进制表示一位。
负数的进制:
原理:负数的二进制表现形式就是对应的正数二进制取反加1。
(2)、进制之间的转换
1.十进制转成二进制 除以2取余数
2.二进制转成十进制 乘以2的幂数
3.十进制转八进制 先把十进制转成二进制,然后3个二进制位,代表品1个八进制位
4.十进制转十六进制 先把十进制转成二进制,然后4个二进制位,代表1个十六进制位
示例:求-6的二进制表现形式
其实就是对应的正数6的二进制取反加1,6的二进制在内存中的表现形式为:
0000-0000 0000-0000 0000-0000 0000-0110
取反: 1111-1111 1111-1111 1111-1111 1111-1001
加1: + 0000-0000 0000-0000 0000-0000 0000-0001
----------------------------------------------------------------------------
1111-1111 1111-1111 1111-1111 1111-1010=-6
负数的二进制最高位永远是1。
六、Java语言的数据类型
Java语言是强类型语言,对于每一种数据都定义了明确的具体数据类型,在内存总分配了不同大小的内存空间。
Java语言的数据类型包括8种基本类型,3种引用类型。
1 byte=1字节=8bit 可表达2的8次方个数字
byte 1个字节 -128---127(27-1)
short 2个字节 -32768---32767
int 4个字节 -65536----65535
long 8个字节
float 4个字节
double 8个字节
char 2个字节
注:
1.long l = 4589653568997L;//error;long l = 4589653568997L;
2.float f = 45.568;//error;float f = 45.568F;
七、基本数据类型转换
byte、short、char之间不会相互转换,它们在计算时首先都会自动转换为int类型。Boolean类型是不可以转换为其他基本数据类型的。
表达式的数据类型自动提升:
所有的byte型、short型和char的值将被提升到int型。
如果一个操作数是long型,计算结果就是long型;
如果一个操作数是float型,计算结果就是float型;
如果一个操作数是double型,计算结果就是double型。
强制类型转换:把一个容量大的数赋值给一个容量小的数时必须要强制类型转换。
示例:
1.byte d=3+4;//编译正常。3和4都是常量,所以java在编译时期会检查该常量的和是否超出byte类型的范围。如果没有可以赋值。
2. byte a=3,b=2;
byte c=a+b;//编译失败。是因为a和b是变量,因为变量的值会变化,不确定具体的值,所以默认使用int类型进行存储。
3.byte e=a++;//编译正常,自带强制转换
byte f+=2;//编译正常,自带强制转换
4.byte b = 3 + 7;
byte b1 = 3;
byte b2 = 7;
b = b1 + b2;
错误原因:涉及到编译器编译程序时候的细节,之所以byte b = 3 +7;,没有报错,是因为3和7都是常量,编译器知道结果是10,并且在byte范围之内,因此就自动进行了强转,所以不会报错。而b = b1 + b2;中b1和b2都是变量,编译器编译程序是一行一行编译的,它根本不知道b1和b2到底是多少,两个byte类型的数据相加时,首先都会被提升为int类型,他们的和也是int类型,其值可能会超过byte的范围,因此就会报错。
八、a++和++a的区别
示例1:
1 int a=3,b; 2 b=a++; 3 System.out.println("a="+a);//a=4 4 System.out.println("b="+b);//b=3
b=a++的特点:先赋值给b,这是b=3;然后a再自增,a+1=4。所以a=4,b=3。简单说就是:先赋值,再自增。
示例2:
1 int a=3,b; 2 b=++a; 3 System.out.println("a="+a);//a=4 4 System.out.println("b="+b);//b=4
b=++a的特点是:先a自增,a+1=4;然后再把自增后的值赋值给b。所以a=4,b=4。简单说就是:先自增,再赋值。
而对于只有a++和++a的时候不管a在前在后,a都自增1,没有区别。
九、java的运算符
(1)、算数运算符
注:
1.整数与整数相除时,结果永远是整数,小数部分被忽略。
2. 负数对正数取模结果为负数; 正数对负数取模结果为正数。即:运算看左边数字的符号。
3.int a = 4,b = 5;
System.out.println("a + b = " + a + b);//a+b=45
System.out.println("a + b = " + (a + b));//a+b=9
(2)、赋值运算符
符号:= , +=, -=, *=, /=, %=
示例:比较a+= 6;和a = a+ 6的不同。
a+=6;语句,编译器在编译的时候,默认内部进行了强制类型转换,也就是将int类型的数据转换成short类型的数据。
a = a+ 6;语句,编译器在编译的时候,默认并没有强制类型转换。如果,a是short类型,而6是int类型,a会自动提升为int类型,相加的和也是int类型,赋值给short类型的变量肯定会损失精度。这时候就需要进行强制类型转换:a = (short)(a + 6);。
(3)、比较运算符
该运算符的特点是:运算完的结果,要么是true,要么是false。
比较运算符“==”不能误写成“=” 。
(4)、逻辑运算符
逻辑运算符用于连接布尔型表达式,在Java中不可以写成3<x<6,应该写成x>3 & x<6 。
&:只有两边都为true时结果为true,否则为false。
|:只有两边都为false时结果为false,否则为true。
^:两边结果一样,就为false;两边结果不一样,就为true。
&和&&的区别:
&:无论左边结果是什么,右边都得参与运算
&&:如果左边为false,那么右边就不用参与运算了。最终结果为false。
|和||的区别:
|:两边都参与运算。
||:只要左边为true,那么右边不用参与运算。最终结果为true。
异或( ^ )与或( | )的不同之处是:当左右都为true时,结果为false。
一个数异或同一个数两次,结果还是这个数。如:6 ^ 3 ^ 3 = 6。
利用异或运算可以实现对数据简单地进行加密。
需求:对两个变量的数据进行互换。
1 class Demo 2 { 3 public static void main(String[] args) 4 { 5 // swap_1(6,9); 6 // swap_2(6,9); 7 swap_2(6,9); 8 } 9 //定义第三方变量相互交换 10 public static void swap_1(int x,int y){ 11 int temp=x; 12 x=y; 13 y=temp; 14 System.out.println("x="+x+", y"+y); 15 } 16 //根据异或两次得原来的数据交换 17 public static void swap_2(int x,int y){ 18 x=x^y; 19 y=x^y; 20 x=x^y; 21 System.out.println("x="+x+", y="+y); 22 } 23 //如果两个整数的数值过大,会超出int范围 24 public static void swap_3(int x,int y){ 25 x=x+y; 26 y=x-y; 27 x=x-y; 28 System.out.println("x="+x+", y="+y); 29 30 } 31 }
(5)、位运算符(左移右移)
位运算是直接对二进制进行运算。
<<:左移,其实就是乘以2的移动的位数次幂
>>:右移,其实就是除以2的移动的位数次幂。
如:3<<2,就是3*22 =3*4=12;
3>>2,就是3/22=3/4=1;
>>:最高位补什么由原有数据的最高位值而定。如果最高位为0,右移后,用0补空位;如果最高位为1,右移后,用1补空位。
>>>>:无论最高位是什么,右移后,都用0补。
1为“真”、“-”,0为“假”、“+”。
(6)、 三元运算符
格式:
(条件表达式)?表达式1:表达式2;
如果条件为true,运算后的结果是表达式1;
如果条件为false,运算后的结果是表达式2;
三元运算符两个表达式一定要有个比较的结果,否则无法使用。
十、java语句
(1)、 判断语句
if语句
三种格式:
1.if(条件表达式)
{
执行语句;
}
2.if(条件表达式)
{
执行语句;
}
else
{
执行语句;
}
3.if(条件表达式)
{
执行语句;
}
else if (条件表达式)
{
执行语句;
}
……
else
{
执行语句;
}
1.如果if语句中只有一条语句,那么可以不写大括号。
2.如果if语句没写大括号,if就只能控制离它最近的单条语句。
if语句特点:
1.每一种格式都是单条语句。
2.第二种格式与三元运算符的区别:三元运算符运算完要有值出现。好处是:可以写在其他表达式中。
3.条件表达式无论写成什么样子,只看最终的结构是否是true 或者 false。
需求:根据用户输入的数值判断所对应的星期。
1 import java.util.Scanner; 2 class IfDemo 3 { 4 public static void main(String[] args) 5 { 6 System.out.println("请输入您的数字:"); 7 Scanner input =new Scanner(System.in);//读取键盘数据 8 int num=input.nextInt(); 9 if (num<1 || num>7)//首先剔除不符合条件的数字 10 { 11 System.out.println("请重新输入有效数字:"); 12 } 13 if(num==1){ 14 System.out.println(num+"所对应的是星期一"); 15 } 16 else if (num==2) 17 { 18 System.out.println(num+"所对应的是星期二"); 19 } 20 else if (num==3) 21 { 22 System.out.println(num+"所对应的是星期三"); 23 } 24 else if (num==4) 25 { 26 System.out.println(num+"所对应的是星期四"); 27 } 28 else if (num==5) 29 { 30 System.out.println(num+"所对应的是星期五"); 31 } 32 else if (num==6) 33 { 34 System.out.println(num+"所对应的是星期六"); 35 } 36 else if (num==7) 37 { 38 System.out.println(num+"所对应的是星期日"); 39 } 40 41 } 42 }
1 import java.util.Scanner; 2 class IfDemo 3 { 4 //可以根据查表法 5 public static void main(String[] args) 6 { 7 System.out.println("请输入您的数字:"); 8 Scanner input =new Scanner(System.in);//读取键盘数据 9 int num=input.nextInt(); 10 String[] week={"","星期一","星期二","星期三","星期四","星期五","星期六","星期日"}; 11 if (num<1 || num>7)//首先剔除不符合条件的数字 12 { 13 System.out.println("请重新输入有效数字:"); 14 } 15 else 16 System.out.println(num+"所对应的是"+week[num]); 17 18 } 19 }
(2)、选择语句
switch语句格式:
switch(表达式)
{
case 取值1:
执行语句;
break;
case 取值2:
执行语句;
break;
…...
default:
执行语句;
break;
}
switch语句特点:
1、switch语句选择的类型只有四种:byte,short,int,char。
2、case与default没有顺序。先执行第一个case,没有匹配的case执行default。
3、结束switch语句的两种情况:1.遇到break,2.执行到switch语句结束。
4、如果匹配的case或者default没有对应的break,那么程序会继续向下执行,运行可以执行的语句,直到遇到break或者switch结尾结束。
5、进入switch语句后,执行顺序是先执行case,然后从上到下,最后再执行default。即使default放在case上面,执行顺序也不变。
需求:根据数字给出所对应的月份
1 import java.util.Scanner; 2 class SwitchDemo 3 { 4 //可以根据查表法 5 public static void main(String[] args) 6 { 7 System.out.println("请输入您的数字:"); 8 Scanner input =new Scanner(System.in);//读取键盘数据 9 int month=input.nextInt(); 10 switch(month){ 11 case 3: 12 case 4: 13 case 5: 14 System.out.println(month + "月对应的是春季" ); 15 break; 16 case 6: 17 case 7: 18 case 8: 19 System.out.println(month + "月对应的是夏季" ); 20 break; 21 case 9: 22 case 10: 23 case 11: 24 System.out.println(month + "月对应的是秋季" ); 25 break; 26 case 12: 27 case 1: 28 case 2: 29 System.out.println(month + "月对应的是冬季" ); 30 break; 31 default: 32 System.out.println(month + "没有对应的季节" ); 33 break; 34 } 35 } 36 }
(3)、循环语句
1.while 循环语句
while语句格式:
while(条件表达式)
{
执行语句;
}
2.do while 循环语句
do while语句格式:
do
{
执行语句;
}while(条件表达式);
do while特点是:无论条件是否满足,循环体至少被执行一次。
3.for循环语句
格式:
for(初始化表达式;循环条件表达式;循环后的操作表达式)
{
执行语句;
}
for循环特点:
1)、for里面的三个表达式运行的顺序,初始化表达式只读一次,判断循环条件,为真就执行循环体,然后再执行循环后的操作表达式,接着继续判断循环条件,重复找个过程,直到条件不满足为止。
2)、while与for可以互换,区别在于for为了循环而定义的变量在for循环结束就是在内存中释放。而while循环使用的变量在循环结束后还可以继续使用。
3)、最简单无限循环格式:while(true) , for(;;),无限循环存在的原因是并不知道循环多少次,而是根据某些条件,来控制循环。
注:
for循环的初始化表达式、循环后的操作表达式可以是多个表达式,通过逗号分隔。
如:
for(int a = 1,b =2; a < 2 & b < 3; a++,b++){
}
嵌套for循环规律:
尖朝上,可以改变条件。让条件随着外循环变化。
尖朝下,可以初始化值,让初始化随着外循环变化。
需求:打印99乘法表
1 class ForDemo 2 { 3 public static void main(String[] args){ 4 for (int x=1;x<10 ;x++ )//外循环控制行数 5 { 6 for (int y=1; y<=x;y++ )//内循环控制每行的个数 7 { 8 System.out.print(y+"*"+x+"="+(y*x)+"\t"); 9 } 10 System.out.println();//换行 11 } 12 } 13 }
需求:打印如下图形。
* * * * * * * * *
* *
* *
* *
* * * * * * * * *
1 class ForDemo2 2 { 3 public static void main(String[] args){ 4 5 //x是控制行数的,当x==0||x==4时,打印的是两条长边 6 //y是控制列数的,当y==0||y==8时,打印的是两条宽边 7 //其余中间就输出空格 8 for (int x=0;x<5 ;x++ ) 9 { 10 for (int y=0;y<9 ;y++ ) 11 { 12 if(x==0||x==4||y==0||y==8) 13 System.out.print("* "); 14 else 15 System.out.print(" "); 16 } 17 System.out.println(); 18 } 19 } 20 }
(4)、其他流程控制语句
break(跳出), continue(继续)
break语句:应用范围:选择结构和循环结构。
continue语句:应用于循环结构。
注:
1),这两个语句离开应用范围,存在是没有意义的。
2),这个两个语句单独存在下面都不可以有语句,因为执行不到。
3),continue语句是结束本次循环继续下次循环。
4),标号的出现,可以让这两个语句作用于指定的范围。
(5)、if、 switch、 do while 、 while 、 for 这些语句什么时候用呢?
1.当判断固定个数的值的时候,可以使用if,也可以使用switch。 但是建议使用switch,效率相对较高。
2.当判断数据范围,获取判断运算结果boolean类型时,需要使用if。
3.当某些语句需要执行很多次时,就用循环结构。
十一、函数
(1)、函数的定义
什么是函数?函数就是定义在类中的具有特定功能的一段独立小程序。函数也称为方法。
(2)、函数的格式
修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,)
{
执行语句;
return 返回值;
}
返回值类型:函数运行后的结果的数据类型。
参数类型:是形式参数的数据类型。
形式参数:是一个变量,用于存储调用函数时传递给函数的实际参数。
实际参数:传递给形式参数的具体数值。
return:用于结束函数。
返回值:该值会返回给调用者。
(3)、函数的特点
1.定义函数可以将功能代码进行封装
2.便于对该功能进行复用
3.函数只有被调用才会被执行
4.函数的出现提高了代码的复用性
5.对于函数没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。
注意:
函数中只能调用函数,不可以在函数内部定义函数。
定义函数时,函数的结果应该返回给调用者,交由调用者处理。
(4)、函数的两个明确
明确要定义的功能最后的结果是什么?
明确在定义该功能的过程中,是否需要未知内容参与运算
(5)、函数重载
在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。
重载的特点:与返回值类型无关,只看参数列表。
重载的好处:方便于阅读,优化了程序设计。
函数的功能一样,仅仅是参与运算的未知内容不同时,可以定义多函数,却使用统一函数名称,这样方便阅读。在调用时,虚拟机通过参数列表的不同来区分同名函数。
需求:打印乘法表。
1 class Test 2 { 3 public static void main(String[] args) 4 { 5 print(3); 6 System.out.println("-------------"); 7 print(); 8 } 9 //因为只是打印乘法表,函数没有什么返回。所以返回值的类型为void 10 public static void print(int num){ 11 for (int x=1; x<=num;x++ ) 12 { 13 for (int y=1;y<=x ;y++ ) 14 { 15 System.out.print(y+"*"+x+"="+(y*x)+"\t"); 16 } 17 System.out.println(); 18 } 19 } 20 public static void print(){//函数重载特性。 21 print(9);//函数调用 22 } 23 }
十二、数组
(1)、数组的定义
同一种类型数据的集合。其实数组就是一个容器。
(2)、数组的好处
以对该容器中的数据进行编号,从0开始。数组用于封装数据,就是一个具体的实体。
(3)、数组的格式
1.元素类型[] 数组名 = new 元素类型[元素个数或数组长度];
int [] arr=new int[6];
2.元素类型[] 数组名 = new 元素类型[]{元素,元素,……};
int[] arr = {3,5,1,7};
int[] arr = new int[]{3,5,1,7};
(4)、数组内存结构
Java程序在运行时,需要在内存中的分配空间。为了提高运算效率,有对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放。
堆内存:
数组和对象,通过new建立的实例都存放在堆内存中。
每一个实体都有内存地址值
实体中的变量都有默认初始化值
实体不在被使用,会在不确定的时间内被垃圾回收器回收
方法区:用来存储方法,静态和共享数据
(5)、数组操作常见问题
1.数组脚标越界异常(ArrayIndexOutOfBoundsException):访问到了数组中的不存在的脚标时发生。
int[] arr = new int[2];
System.out.println(arr[3]);
2.空指针异常(NullPointerException):当引用型变量没有指向任何实体时,用其操作实体,就会发生该异常。
int[] arr = null;
System.out.println(arr[0]);
(6)、数组常见操作
1.获取最值(最大值,最小值)
获取最大值代码演示:
1 class ArrayDemo 2 { 3 public static void main(String[] args) 4 { 5 int[] arr={17,45,10,2,6,789,-45}; 6 int max=getMax(arr); 7 System.out.println("max="+max); 8 System.out.println("-------------"); 9 int m=getMax_2(arr); 10 System.out.println("max="+m); 11 } 12 //根据数组的值大小获取 13 public static int getMax(int[] arr){ 14 int max=arr[0]; 15 for (int x=1;x<arr.length ;x++ ) 16 { 17 if(max<arr[x]) 18 max=arr[x]; 19 } 20 return max; 21 } 22 //根据角标获取最大值 23 public static int getMax_2(int[] arr){ 24 //先用变量记录角标0. 25 int maxIndex=0; 26 for (int x=1;x<arr.length ;x++ ) 27 { 28 //如果maxIndex角标上的值大于x角标上的值 29 if(arr[maxIndex]<arr[x]) 30 maxIndex=x;//获取较大值的角标 31 } 32 return arr[maxIndex]; 33 } 34 }
获取最小值代码演示:
1 class ArrayDemo2 2 { 3 public static void main(String[] args) 4 { 5 int[] arr={17,45,10,2,6,789,-45}; 6 int min=getMin(arr); 7 System.out.println("min="+min); 8 } 9 public static int getMin(int[] arr){ 10 int min=arr[0]; 11 for (int x=1; x<arr.length; x++) 12 { 13 if(min>arr[x]) 14 min=arr[x]; 15 } 16 return min; 17 } 18 }
2.排序(选择排序,冒泡排序)
选择排序思路:每次循环结束后数组前面的小元素都确定下来了。
(1)、首先拿数组第一个元素依次与除其自身外的其他每个元素顺序比较,如果第一个元素大于剩下的某个元素,就互换内容。
(2)、经过第一轮比较之后,此时,第一个元素就是数组中最小的元素。然后再拿第二个元素与除第一个元素和其自身的元素进行比较,如果第二个元素大于剩下的某个元素,就互换内容。此时,第二个元素就是数组中倒数第二小的元素。
(3)、依次类推,直到最后一个元素。
1 class ArrayDemo 2 { 3 public static void main(String[] args) 4 { 5 int[] arr={17,45,10,2,6,789,-45}; 6 selectSort(arr); 7 printArray(arr); 8 } 9 public static void printArray(int[] arr){ 10 for (int x=0;x<arr.length ;x++ ) 11 { 12 if(x<arr.length-1) 13 System.out.print(arr[x]+","); 14 else 15 System.out.print(arr[x]); 16 } 17 } 18 public static void selectSort(int[] arr){ 19 for (int x=0;x<arr.length-1 ;x++ ) 20 { 21 for (int y=x+1;y<arr.length ;y++ ) 22 { 23 if(arr[x]>arr[y]){ 24 int temp=arr[x]; 25 arr[x]=arr[y]; 26 arr[y]=temp; 27 } 28 } 29 } 30 } 31 }
冒泡排序思路:每次循环结束后最大的值都在数组的后面,就像水中的气泡一样越往上升,气泡越大。
思路:
1、首先在第一轮排序中,数组从第一个元素到倒数第二个元素依次与其右边的元素进行比较,如果左边的元素大于右边的元素,那么两个元素就互换。
2、经过第一轮比较,最大的元素就已经存储到数组最右边的结点中了。
3、第二轮排序则是从第一个元素到倒数第三个元素依次与其右边的元素进行比较,如果左边的元素大于右边的元素,那么两个元素就互换。
4、依照此方式,一直到只有第一和第二个元素互相比较而结束。
class ArrayDemo2 { public static void main(String[] args) { int[] arr={17,45,10,2,6,789,-45}; bubbleSort(arr); printArray(arr); } 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.print(arr[x]); } } 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; } } } } }
其实java中已经封装好了数组排序的方法。在util工具包中Arrays类中专门操作数组的工具类。Arrays.sort(arr);就可以直接操作数组排序。
3.查找
简单遍历查找:
如果一个数组是无序的,那么可以通过简单遍历查找的方式查找到某个元素所在的角标。
1 简单遍历查找: 2 class Demo{ 3 public static void main(String[] args){ 4 int [] arr={4,1,54,89,-127,4}; 5 int index=getKey(arr,-127); 6 System.out.println(“index=”+index); 7 } 8 public static int getKey(int[] arr,int key){ 9 for(int x=0;x<arr.length;x++){ 10 if(arr[x]==key) 11 return x; 12 } 13 return -1; 14 } 15 }
折半查找(二分查找):数组必须有序
如果一个数组是有序的,那么就可以通过一种更高效的方式达到相同的目的,也就是二分查找。
思路:
1、设置三个变量记录角标:min、max、mid。min初始值为0,max为数组最大角标,mid为(max+min)/2。
2、查看mid角标的元素是否与待查找的值相等,如果相等,则直接返回角标值,程序终止执行。
3、如果待查找的值小于角标为mid的元素值,那么说明待查找的元素的位置可能在min与mid角标之间。设置max = mid - 1,mid = (max + min)/2,重复第1、2步的操作。
4、如果待查找的值大于角标为mid的元素值,那么说明待查找的元素的位置可能在mid与max角标之间。设置min = mid + 1,mid = (max + min)/2,重复第1、2步的操作。
5、如果数组中不存在待查找的元素,那么按照如上流程,最终min角标值会大于max角标值,此时返回-1。
1 import java.util.*; 2 class ArrayDemo 3 { 4 public static void main(String[] args) 5 { 6 int[] arr={17,45,10,2,6,789,-45}; 7 Arrays.sort(arr); 8 int index=halfSearch(arr,10); 9 System.out.println("index="+index); 10 } 11 public static int halfSearch(int[] arr,int key){ 12 int min=0,max=arr.length,mid=(min+max)/2; 13 while (min<=max) 14 { 15 mid=(min+max)/2; 16 if(key>arr[mid]){ 17 min=mid+1; 18 } 19 else if (key<arr[mid]) 20 { 21 max=mid-1; 22 } 23 else 24 return mid; 25 } 26 return -1; 27 } 28 } 29
需求:给定一个有序的数组,如果往该数组中存储一个元素,并保证这个数组还是有序的,那么这个元素的存储的角标如何获取?
思路:可以先通过二分查找,返回min的值,然后将待插入元素存在角标为min的数组位置,数组中角标为min以及比min大的角标所在的数组元素全部往后顺延一个位置。
1 import java.util.*; 2 class ArrayDemo 3 { 4 public static void main(String[] args) 5 { 6 int[] arr={17,45,10,2,6,789,-45}; 7 Arrays.sort(arr); 8 int index=halfSearch(arr,100); 9 System.out.println("index="+index); 10 } 11 public static int halfSearch(int[] arr,int key){ 12 int min=0,max=arr.length,mid=(min+max)/2; 13 while (min<=max) 14 { 15 mid=(min+max)/2; 16 if(key>arr[mid]){ 17 min=mid+1; 18 } 19 else if (key<arr[mid]) 20 { 21 max=mid-1; 22 } 23 else 24 return mid; 25 } 26 return min;//index=6,表示插入点的位置是数组中角标位6的地址,其他比100大的数值往后顺延。 27 } 28 } 29
java中已经封装好了数组二分查找的方法。在util工具包中Arrays类中专门操作数组的工具类。Arrays.binarySearch(arr,78)可直接二分查找。
十三、二维数组
二维数组:数组中的数组。二维数组:int[][]。
(1)、二维数组的格式
1.int[][] arr = new int[3][2];
定义了名称为arr的二维数组
二维数组中有3个一维数组
每一个一维数组中有2个元素
一维数组的名称分别为arr[0], arr[1], arr[2]
给第一个一维数组1脚标位赋值为78写法是:arr[0][1] = 78;
2.int[][] arr = new int[3][];
二维数组中有3个一维数组
每个一维数组都是默认初始化值null
可以对这个三个一维数组分别进行初始化
arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];
3.int[][] arr = {{3,8,2},{2,7},{9,0,1,6}};
定义一个名称为arr的二维数组
二维数组中的有三个一维数组
每一个一维数组中具体元素也都已初始化
第一个一维数组 arr[0] = {3,8,2};
第二个一维数组 arr[1] = {2,7};
第三个一维数组 arr[2] = {9,0,1,6};
第三个一维数组的长度表示方式:arr[2].length;
注意特殊写法情况:int[] x,y[]; x是一维数组,y是二维数组。
需求:求二维数组所有元素的和。
1 import java.util.*; 2 class ArrayDemo2 3 { 4 public static void main(String[] args) 5 { 6 int[][] arr={{3,8,2},{2,7},{9,0,1,6}}; 7 int sum=getSum(arr); 8 System.out.println("sum="+sum); 9 } 10 public static int getSum(int[][] arr){ 11 int sum=0; 12 for (int x=0;x<arr.length ;x++ )//外循环遍历二维数组的长度 13 { 14 for (int y=0;y<arr[x].length ;y++ )//内循环遍历每个一维数组的长度 15 { 16 sum+=arr[x][y]; 17 } 18 } 19 return sum; 20 } 21 }