分支结构
Java 提供两种常见的分支控制结构:if 语句和 switch 语句。
if 语句使用布尔表达式或者布尔值作为分支条件来进行分支控制。
switch 语句用于对多个整型值进行匹配,从而实现分支控制,后面的控制表达式的数据类型只能是 byte、short、char、int四个数据类型和枚举类型。
这个感觉和C语言基本没差。
循环结构
循环结构中的语句有: while( ) , do while( ) , for( ) 等都和C语言差不多。
控制循环的语句有: break, continue , return 。
众所周知 break 语句可以结束其所在的循环。但如果在 break 后使用标签控制还可以结束外层循环。
public class BreakTest
{
public static void main( String [] args )
{
outer:
for(int i=0; i<5; i++)
{
for(int j=0; j<3; j++)
{
System.out.println("i的值为:" + i + "j的值为:" + j);
if(j == 1)
{
break outer;
}
}
}
}
}
如上代码示例,不过使用标签 break 时必须保证此标签有效。
continue 终止本次循环,然后开始下一次循环。同样的方法在 continue 尾部使用标签可直接开始下一次循环,内层循环没有机会执行完成。
数组类型
数组是编程语言中一种常见的数据结构,可用于存储多个数据,每个数组元素存放一个数据,通常可通过数组元素的索引来访问数组元素,包括为数组元素赋值和取出数组元素的值。
Java 的数组可以存储基本类型的数据,也可以存储引用类型的数据,只要所有的数据类型具有相同的类型即可。
值的提出的是,数组也是一种数据类型,与 int、string 类型类似,可以使用该类型来定义变量,也可以使用该类型进行类型转换。 它也是一种引用类型,创建 int[] 类型对象也就是创建数组,需要使用创建数组的语法。
//可使用这两种格式定义数组
type[] arrayName;
type arrayName[];
数组初始化分为静态初始化和动态初始化。
//静态初始化
arrayName = new type[]{element1,element2,element3, ...};
//动态初始化只指定数组长度,由系统默认初始化值
arrayName = new type[length];
系统初始化规则
- 整数类型: 0
- 浮点类型:0.0
- 字符类型:‘\u0000’
- 布尔类型:false
- 引用类型:null
Java 提供了一种简单的遍历数组和集合的循环——foreach。此循环无需获得数组长度,无需通过索引访问,能自动遍历数组和集合中的每个元素。
深入数组
与所有引用变量相同的是,引用变量是访问真实对象的根本方式。实际的数组对象内存储在堆内存中,如果引用该数组对象的数组引用变量是一个局部变量,那么它被存储在栈内存中。 存储示意图如下:
堆内存和栈内存之分
栈: 当一个方法被执行时,这个方法会建立自己的内存栈,在这个方法内定义的变量会逐步放入这块栈内存中,方法结束时,此栈销毁。因此,所有方法定义的局部变量都是放在栈内存中的。
堆: 当我们在程序中创建一个对象时,这个对象将被保存到运行时的数据区,以便反复使用。这个运行时的数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁。此方法结束,可使用下一方法来引用。只有当一个对象没有任何变量引用它时,系统的垃圾回收器才在合适时候回收它。也可以直接将对内存的数据赋值为 null,提醒系统来回收它。
也就是说,如果仅定义一个变量,int[] array;
则只在栈内存中定义一个数组变量,堆内存没东西。
来看一个例子了解下数组本身和引用的区别:
public class ArrayInRam
{
public static void main( String[] args )
{
int[] a = {5, 7, 20};
int[] b = new int[4];
System.out.println("b数组的长度为" + b.length);
for(int i=0; i<a.length; i++)
{
System.out.println( a[i] );
}
for(int i=0; i<b.length; i++)
{
System.out.println(b[i]);
}
b = a;
System.out.println("B数组的长度为" + b.length);
}
}
运行结果:
如图,上面都是预期结果,最后一句,b数组的长度变成3。如上面堆内存和栈内存的描述,当程序定义并初始化了a,b两个数组后,系统内存实际上产生了4块内存区,其中栈内存中有两个引用变量 a 和 b,堆内存中也有 a 和 b 两个内存区永来存储数据本身。当执行 b=a 时,系统把 a 赋给 b,两个都是引用类型变量,因此把 a 赋给 b,就是让 b 指向 a 所指向的地址。此是堆内存中的 a 变量和 b 变量都引用了第一个数组。第二个数组失去引用变成垃圾。
Java 中未提供多维数组,但 Java 数组里的语言是引用类型,这个引用指向真实的数组内存。数组元素的类型也可以是引用,如果数组元素的引用再次指向真实的数组内存,就能当多维数组用了。
定义格式 :type[][] arrName;
操作数组的工具类
Java 提供的 Arrays 类中包含的一些 static 修饰的方法可以直接操作数组。
Array 类处于 java.util 包下,为了在程序中使用 Arrays 类,必须在程序中导入 java.util.Arrays 类。
int binarySearch(type[] a, type key):
使用二分法查询 key 元素在 a 数组中出现的索引。调用该方法要求数组中元已经按升序排列。int binarySearch(type[] a, int fromIndex, int toIndex, type key):
在上一个方法的基础上定义了区间。type[] copyOfRange(type[] original, int newlength):
将original数组赋值成一个新数组。如果length小了,只复制original中前length个,如果length大了,后面补0,false,null。type[] copyOfRange(type[] original, int from, int to):
复制from索引到to索引的内容。boolean equals(type[] a, type[] a2):
如果a和a2数组长度和元素都相等,则返回true。void fill(type[] a, type cal):
该方法将会把a数组的所有元素赋值给val。void fill(type[] a, int fromIndex, int toIndex, type val):
将指定去见的数组元素赋值为val。void sort(type[] a):
堆对数组元素进行排序。void sort(type[] a, int fromIndex, int toIndex):
将指定区间元素排序。String toString(type[] a):
将一个数组转换为一个字符串。该方法按顺序把多个数组元素连缀在一起,多个数组元素使用英文逗号和空格隔开。
应用实例
将一个浮点数转换为人民币读法字符串,分两步:
1. 将浮点数分成两个数字字符串。
2. 将数字字符串转换为人民币读法。
步骤清晰后,即可封装类NumRmb。
import java.util.Arrays;
public class Num2Rmb
{
private String[] hanArr = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
private String[] unitArr = {"十","百","千"};
/*return 分解出来的整数部分和小数部分*/
private String[] divide(double num)
{
long zheng = (long)num;
long xiao = Math.round((num - zheng) * 100); //Math.round给指定的值四舍五入为整数
return new String[]{zheng + "", String.valueOf(xiao)};
}
/*把一个人四位的数字字符串变成汉字字符串*/
private String toHanStr( String numStr )
{
String result = ""; /*定义结果字符串,等会一个一个添加*/
int numLen = numStr.length(); /*计算数字字符串长度*/
for(int i=0; i<numLen; i++)
{
int num = numStr.charAt(i) - 48; /*.charAt(i)取出指定位置的字符,char类型减去48得到int型*/
if( i != numLen-1 && num != 0) /*当前取出数字不是最末尾的,也不是零*/
{
result += hanArr[num] + unitArr[numLen-i-2];
}
else
{
result += hanArr[num];
}
}
return result;
}
}
这里只实现了四位数字以下的人民币转换。