Java基础语法(二)
承接基础语法。
上一篇漏了三元运算符。
在这里记忆一遍。
三元运算符
格式:
(条件表达式)?表达式1:表达式2;
如果条件为真,那么结果是表达式1
如果条件为假,那么结果是表达式2
例子:
去两个数中的最大数:
int x=3,y=4,z;
z = (x>y)?x:y;
下面记录java语法当中的程序流程控制。
程序流程控制
选择语句
if语句
if语句的三种格式
第一种:
if(条件)
{
执行语句;
}
第二种
if(条件)
{
执行语句;
}
else
{
执行语句;
}
第三种
if(条件)
{
执行语句;
}
else if (条件)
{
执行语句;
}
else
{
执行语句;
}
(上面的表达式,使用的时候一定把全角字符变成半角。要不然会编译失败的哟)
每一种格式都是单挑语句
第二种格式与三元运算符运算的区别: 三元运算符运算完必须有值的出现,好处是可以写在其他的表达式中,可以精简代码。
条件表达式,无论写成什么样,只看最后结果是否是真和假。
switch语句
格式:
switch (表达式)
{
case 取值1:
执行语句;
break;
case 取值2:
执行语句;
break;..................
default ;
执行语句;
break;}
switch特点:
switch语句可以选择的类型:byte, int, short ,char
case与default没有顺序,程序进来先执行第一个case,case执行完判断结果全为假会执行default
结束switch语句有两种情况:遇到break ,执行到switch结束。
如果匹配的case或者default没有对应break语句,那么程序会继续向下执行每一条语句,直到遇到break或者执行到程序的结束。
switch可选择类型:JDK 1.5以后可以是枚举,JDK 1.7以后可以是字符串
循环语句
while语句
格式:
while (条件)
{
执行语句;
}
do while 语句
格式:
do
{
执行语句;
}
while (条件)
特点:无论条件是否满足,都会至少执行一遍执行语句。
for循环
for (初始化表达式;条件表达式;循环后的操作)
{
执行语句;
}
例:
for (int x=0;x<3;x++)
{
System.out.println("x="+x);
}
for循环的顺序,1先执行初始化表达式,2条件表达式,3执行语句,4循环后操作,5条件表达式,6执行语句,7循环后操作,8条件表达式..........
直到条件表达式的值为假,或者遇到break语句。循环结束。
for使用多条件或者多表达式的时候,用“,”隔开。
注意:
每个变量都有自己的作用域,对于for语句,如果将用于控制循环的增量定义在for中,那么该便娘只能在for中有效,for执行后该变量所占的内存会自动释放。
for和while可以进行互换,如果只是需要定义循环增量作为变量的话,那么用for更合适。
书写循环代码的时候,一定要明确那些语句是需要循环的,那些是不需要循环的。
总结:什么时候使用循环。
当要对某些语句执行多次,用循环语句,当需要计算循环的执行次数的时候,使用while语句,当只用作循环增量,那么用for语句。
死循环的最简单表现形式:
for(;;){}//对于for来说,默认的条件为true
while(true){}
累加思想
通过变量记录每次变化的结果,通过循环的形式进行累加动作。
计数器思想
通过一个变量记录住数据的状态变化,也许通过循环来完成。
循环嵌套:
就是循环套循环。
例:
for (int x=0;x<3;x++)
{
for (int y=0;y<3;y++)
{
System.out.print("*");
}
System.out.println();//用来换行。
}
这段代码,会打印出一个长方形,外循环控制行,内循环来控制每行的个数。
其他控制语句
break:跳出,用在选择和循环中
continue:继续,用在循环中
注意:
break和continue语句离开应用范围是没有意义的。
这来年哥哥语句单独存在的时候,语句下面不可以有其他语句,会编译失败,原因是因为下面的语句执行不到。
continue语句是结束本次循环执行下一次循环。
break是结束循环
标号
标号的出现可以让continue和break语句作用在指定的范围。
w: for (int x=0;x<3;x++)
{
q: for (int y=0;y<3;y++)
{
System.out.print("*");
break w;
}
System.out.println();//用来换行。
函数
函数就是定义在类中的具有特定功能的一段独立的程序。也称之为方法。
int x= 4;
System.out.print(x*3+5);
x=6;
System.out.print(x*3+5);
我们发现,以上的运算中,因为互殴不同数据的运算结果的代码出现重复,为了提高代码的复用性,对代码进行抽取,
将这部分代码定义(封装)成一个独立的功能,以便日后使用。
在java中对功能的定义是通过函数来完成的。
那么就需要定义一个方法,来完成x*3+5的运算。
函数的格式
修饰符 返回值类型 函数名 (参数类型 形参1,参数类型 形参2,参数类型 形参3 .....)
{
执行语句;
return 返回值;
}
例:
public static int getResult (int num)
{
return num*3+5
}
//调用方法
x = getResult(4);
定义函数可以将功能代码进行封装,以便于对该功能进行复用。
当函数运算后,没有具体的返回值的时候,用一个关键字void来标识。
void:代表的是函数没有具体的返回值额情况,当函数的返回值为void的时候,return可以不写
函数的重载
(overload)
在同一个类中,允许存在一个以上的同名函数,要求是他们的参数列表不同。
重载的特点:
与返回值类型无关,值看参数列表。
重载的好处:
方便阅读,优化了程序设计。
例:
//返回两个整数的和
int add (int x ,int y){return x+y;}
//返回三个整数的和
int add (int x ,int y,int z){return x+y+z;}
double add (double x,double y){return x+y;}
数组
概念:同一种类型数据的集合。(毕老师语:其实数组就是一个容器。)
数组的好处:可以自动给数组中的元素从0开始编号,方便操作这些元素。
数组的格式:
元素类型[] 数组名 = new 元素类型[元素个数或者数组长度]
例:int [] arr = new[5];
格式2:
元素类型[] 数组名 ={1,2,3,4,5,6,7};可以直接指定具体的数据
格式3:
元素类型[] 数组名;
数组的特点:
1)数组定义时,必须明确数组的长度(就是数组中可以存储的元素的个数。)
因为数组长度是固定的。
2)数组定义时,必须明确数组中的元素的数据类型。
内存结构
java中需要在内存中分配空间提高运算效率,对空间进行不同区域的划分,每个区域都有自己特定的处理数据的方式和内存管理的方式。
栈内存:
用于储存局部变量,当数据使用完之后,数据所占内存会自动释放。
堆内存:
数组和对象通过new建立实例的时候都储存在堆内存中。
每一个实体都有一个相对应的地址值
实体中的变量都有默认的初始化值,实体不再被使用,会在不确定时间内被java中自带的垃圾回收器回收。
其他内存
方法区 本地方法区 寄存器。
数组操作常见的问题
ArrayIndeOutOfBandsException
数组越界,如果定义一个数组的长度为3,那么该数组的只有3个元素,即:0,1,2。当使用角标为3的元素时,由于超过定义时数组的长度,会出现角标越界问题。
NullPointerException
空指针异常,当把null赋值给一个数组时,该数组所对应的地址值会变为null,那么使用具体的地址的时候就会出现空指针问题
上图是建立数组时的内存结构。
一般当char[] arr语句执行的时候会在栈内存中开辟一个空间,用来存储数组名和对应在堆内存中的地址,这个时候栈内存中存储的地址是null,
当new char[5]被执行到的时候,会在堆内存中开辟一个空间用来存放数组中的各个元素,开辟的时候,第一个元素的地址就会赋值给arr,
以上就是数组与栈内存与堆内存的关系。
如何获取数组中的值
要获取数组中的值一般使用循环语句对数组中的各个元素进行遍历。
例:
int [] arr = new{1,5,6,7};
for (int i = 0;i<arr.length;i++)
{
System.out.println("int["+i+"]="+arr{i});
}
输出结果
int[0]=1
int[1]=5
int[2]=6
int[3]=7
数组中有一个属性,length,意义是返回数组的长度。
用法是: 数组名.length
如果直接打印数组,那么会打印出数组的地址,
例:打印的结果 [I@dec6ced
其中[指的是数组,I表示数组类型,后面@的是数组所对应堆内存的地址值
数组应用
求数组的极值
思路:用循环遍历数组,对每个数组的元素进行比较,保留极值
int [] arr = new{1,5,6,7,10,0,9};
int num = arr[0];
for (int i = 0;i<arr.length;i++)
{
if (num<arr[i])//跟据取的极值不同,用不同的比较方法。
num = arr[i]
}
获取极值的另一种方法,可不可以将临时变量初始化为0,
答:可以,这种方式其实就是将变量在初始化为数组的角标,
方法:
int [] arr = new{1,5,6,7,10,0,9};
int num =0;
for (int i = 0;i<arr.length;i++)
{
if (arr[num]<arr[i])//跟据取的极值不同,用不同的比较方法。
num = i;
}
对两种方式的总结:其实第一种是对元素进行操作,第二种是针对角标的操作,第一种方法比较直观,第二种方法比较抽象,最后的结果都是一致的。
排序
class Sorttest { void Sort1() { System.out.println("---选择排序法------------"); int arr1[] = {23,56,12,7,65,100,32,12}; //排序前数组的值 for (int i = 0;i<arr1.length;i++) System.out.println("arr1["+i+"]="+arr1[i]); System.out.println("------------------------"); //排序后数组的值 for (int a=0;a<arr1.length;a++) { for (int b=a+1;b<arr1.length;b++) { if(arr1[a]>arr1[b]) { int temp; temp = arr1[a]; arr1[a] = arr1[b]; arr1[b] = temp; } } } for (int i = 0;i<arr1.length;i++) System.out.println("arr1["+i+"]="+arr1[i]); System.out.println("---冒泡排序法------------"); int arr2[]= {11,22,33,11,2,1,445,33,253,1,0,2,34,4,5,10,9}; //排序前数组的值 for (int i = 0;i<arr2.length;i++) System.out.println("arr2["+i+"]="+arr2[i]); System.out.println("------------------------"); //排序后数组的值 for (int a=0 ; a<arr2.length-1 ; a++) { for (int b=0 ; b<arr2.length-a-1 ; b++)//-a是为了每一次减少a,-1是为了防止数组越界 { if(arr2[b]>arr2[b+1]) { int temp; temp = arr2[b]; arr2[b] = arr2[b+1]; arr2[b+1] = temp; } } } for (int i = 0;i<arr2.length;i++) System.out.println("arr2["+i+"]="+arr2[i]); } }选择排序法:
其实就是从第一个元素开始,依次对比剩下的元素,取得极值,结果就是极值元素选择到第一位,然后是第二位、第三..........
冒泡排序法,相邻的元素比较,那么极值会走到最后一个位置。
以上俩个排序方法都是使用嵌套循环,对数组中的元素进行遍历和比较。
最快的排序方法:希尔运算
项目中使用的排序方法:
import java.util.Arrays;
Arrays.sort(arr);
利用数组进行进制转换
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; arr[--pos] = chs[temp]; num = num >>> 1; } for(int x=pos; x<arr.length; x++){ System.out.print(arr[x]); } } 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; } System.out.println("pos="+pos); //存储数据的arr数组遍历。 for(int x=pos;x<arr.length; x++) { System.out.print(arr[x]); } } //二进制 public static int toBin(int num){ trans(num,1,1); } //八进制 public static int toBa(int num){ trans(num,7,3); } //十六进制 public static int toHex(int num){ trans(num,15,4); }
总结:以上的代码,是将数组作为一个容器,巧妙的利用了二进制的位运算。
查表法:将要使用的数据全部存储进一个临时容器中,然后建立关系,最后进行查找。
二维数组
二维数组就是数组中的数组。
二维数组的元素就是一个一个的一维数组。
格式
格式1:元素类型[][] 数组名 = new 元素类型[3][2];
例:int[][] arr = new int [2][4];//就是定义了名字为arr的二维数组,二维数组有三个元素,分别是arr[0][4],arr[1][4],arr[2[4],每个元素都是一个具有5个元素的一维数组。
arr[0][2] = 30;//就是对索引为0 2的这个元素进行赋值。
格式2:元素类型[][] 数组名 = new 元素类型[3][];
这样定义是可以的,说明了这个二维数组有4个一维数组,每一个一维数组的初始值为null。
格式3:元素类型[][] 数组名 = {{一维数组元素}{一维数组元素}{一维数组元素}};//直接对所有的元素进行初始化,一般用在不规则数组上。
二维数组的长度为:
arr.length
二维数组中的一个一维数组元素的长度为:
arr[x].length
取得二维数组值需要双循环对数组进行遍历输出。
数组的表现形式:
一维数组可以有:
int [] x;
int x [];
二维数组可以有:
int [][] y;
int y [][];
int [] y [];
这个是啥?
int[]x,y[];
x是一个一维数组,y是一个二维数组
这么写leader会疯的。
以上就是这篇笔记,主要记述了流程控制语句,数组。
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------