Java 流程控制与数组
順序結構
程序從上到下逐行地執(zhí)行,中間沒有任何判斷和跳轉。
分支結構
if條件語句
if語句使用布爾表達式或布爾值作為分支條件來進行分支控制。
第一種形式:if(logic expression){statement...} 第二種形式: if(logic expression){statement...} else{statement...} 第三種形式:if(logic expression){statement...} else if(logic expression){statement...} ...// 可以有兩個或多個else if語句 else// 最后的else語句也可以省略{statement...}花括號括起來的多行代碼稱為代碼塊,一個代碼塊通常被當成一個整體來執(zhí)行(除非運行過程中遇到return、break、continue等關鍵字,或者遇到了異常)。以上代碼塊又稱為條件執(zhí)行體
if、else、else if后的條件執(zhí)行體要么是一個花括號括起來的代碼塊,則這個代碼塊整體作為條件執(zhí)行體;要么是以分號為結束符的一行語句,甚至可能是一個空語句(空語句是一個分號),那么就只是這條語句作為條件執(zhí)行體。如果省略了if條件后條件執(zhí)行體的花括號,那么if條件只控制到緊跟該條件語句的第一個分號處
使用if...else語句時,優(yōu)先處理包含范圍更小的情況
switch分支語句
switch語句后面的控制表達式的數(shù)據(jù)類型只能是byte、short、char、int四種整數(shù)類型、枚舉類型和java.lang.String類型,不能的boolean類型
switch(expression) {case condition1:{statement(s)break;}case condition2:{statement(s)break;}...case conditionN:{statement(s)break;}default:{statement(s)} }允許switch語句的控制表達式是jaca.lang.String類型的變量或者表達式,不能是StringBuffer或StringBuilder這兩種字符串類型。
循環(huán)結構
循環(huán)語句可能包括如下4個部分
初始化語句、循環(huán)條件、循環(huán)體、迭代語句
建議不要在循環(huán)體內(nèi)修改循環(huán)變量(循環(huán)計數(shù)器)的值,否則會增加程序出錯的可能性。若必須訪問、修改循環(huán)變量的值,建議重新定義一個臨時變量,先將循環(huán)變量的值賦給臨時變量,然后對臨時變量的值進行修改
while循環(huán)語句
[init_statement] while(test_expression) // 后面無分號;!!! {statement;[iteration_statement] }do while循環(huán)語句
[init_statement] do {statement;[iteration_statement] }while(test_expression);for循環(huán)
for([init_statement];[test_statement];[iteration_statement]) {statement; } 建議不要在循環(huán)體內(nèi)修改循環(huán)變量的值,否則會增加程序出錯的可能性。 額外定義一個變量來保存這個循環(huán)變量的值tmp = i; 選擇循環(huán)變量時,習慣選擇i、j、k來作為循環(huán)變量。嵌套結構
控制循環(huán)結構
使用break結束循環(huán)
某些時候需要在某種條件出現(xiàn)時強行終止循環(huán),而不是等到循環(huán)條件為false時才推出循環(huán)。此時,可以使用break來完成這個功能。break用于完全結束一個循環(huán),跳出循環(huán)體。
break語句不僅可以結束其所在的循環(huán),還可以直接結束其外層循環(huán)。此時需要在break后緊跟一個標簽,這個標簽用于標識一個外層循環(huán)。Java中的標簽只有放在循環(huán)語句之前才有作用。
public class BreakTest2 {public static void main(String[] args){//外層循環(huán),outer作為標識符outer:for(int i = 0; i < 5; i++){System.out.println("i的值為:" + i + " j的值為:" + j);if(j == 1){//跳出outer標識所標識的循環(huán)break outer;}}} }程序從外層循環(huán)進入內(nèi)存循環(huán)后,當j等于1時,程序遇到一個break outer;語句,這行代碼將會導致結束outer標識指定的循環(huán),不是結束break所在的循環(huán),而是結束break循環(huán)的外層循環(huán)。
通常緊跟break之后的標簽,必須在break所在的循環(huán)的外層循環(huán)之前定義才有意義。
使用continue忽略本次循環(huán)剩下語句
continue只是忽略本次循環(huán)剩下語句,接著開始下一次循環(huán),并不會終止循環(huán);而break則是完全終止循環(huán)本身。
public class ContinueTest2 {public static void main(String[] args){//外層循環(huán)outer:for(int i = 0; i < 5; i++){System.out.println("i的值為:" + i + " j的值為:" + j);if(j == 1){//跳出outer標識所標識的循環(huán)中本次循環(huán)所剩下的語句continue outer;}}} }通常緊跟continue之后的標簽,必須在continue所在的循環(huán)的外層循環(huán)之前定義才有意義。
使用return結束方法
return關鍵字并不是用于結束循環(huán)的,return的功能是結束一個方法。當一個方法執(zhí)行到一個return語句時(return關鍵字后還可以跟變量、常量和表達式),這個方法將被結束。
數(shù)組類型
理解數(shù)組:數(shù)組也是一種類型
一旦數(shù)組的初始化完成,數(shù)組在內(nèi)存中所占的空間將被固定下來,因此數(shù)組的長度將不可改變。即使把某個數(shù)組元素的數(shù)據(jù)清空,但它所占的空間依然被保留,依然屬于該數(shù)組,數(shù)組的長度依然不變。
定義數(shù)組
type[] arrayName;數(shù)組是一種引用類型的變量,因此使用它定義一個變量時,僅僅表示定義了一個引用變量(也就是定義了一個指針),這個引用變量還未指向任何有效的內(nèi)存,因此定義數(shù)組時不能指定數(shù)組的長度。而且由于定義數(shù)組只是定義了一個引用變量,并未指向任何有效的內(nèi)存空間,所以還沒有內(nèi)存空間來存儲數(shù)組元素,因此這個數(shù)組也不能使用,只有對數(shù)組進行初始化后才可以使用。
數(shù)組的初始化
所謂初始化,就是為數(shù)組的數(shù)組元素分配內(nèi)存空間,并為每個數(shù)組元素賦初始值。
靜態(tài)初始化
arrayName = new type[]{element1, element2, element3...}; 簡化的語法格式: type[] arrayName = {element1, element2, element3...};動態(tài)初始化
動態(tài)初始化只指定數(shù)組的長度,由系統(tǒng)為每個數(shù)組元素指定初始值。
arrayName = new tpye[length]; int[] prices = new int[5] // 數(shù)組的定義和初始化同時完成,使用動態(tài)初始化語法。默認值
整數(shù)類型 byte、short、int、long 0 浮點類型 float、double 0.0 字符類型 char \u0000 布爾類型 boolean false 引用類型 類、接口、數(shù)組 null使用數(shù)組
數(shù)組索引是從0開始的,第一個數(shù)組元素的索引值為0,最后一個數(shù)組元素的索引值為數(shù)組長度減1。
如果訪問數(shù)組元素時指定的索引值小于0,或者大于等于數(shù)組的長度,編譯程序不會出現(xiàn)任何錯誤,但運行時會出現(xiàn)異常:java.lang.ArrayIndexOutOfBoundsException:N(數(shù)組索引越界異常),異常信息后的N就是程序員試圖訪問的數(shù)組索引。
所有的數(shù)組都提供了一個length屬性,通過這個屬性可以訪問到數(shù)組的長度,一旦獲得了數(shù)組的長度,就可以通過循環(huán)來遍歷該數(shù)組的每個數(shù)組元素。
foreach循環(huán)
使用foreach循環(huán)遍歷數(shù)組和集合元素時,無需獲得數(shù)組和集合長度,無需根據(jù)索引來訪問數(shù)組元素和集合元素,foreach循環(huán)自動遍歷數(shù)組和集合的每個元素。
foreach循環(huán)的語法格式如下:
for(type variableName : array | collection) {// variableName 自動迭代訪問每個元素... }public class ForEachTest {public static void main(String[] args){String[] books = {"輕量級Java EE企業(yè)應用實戰(zhàn)","瘋狂Java講義","瘋狂Android講義"};// 使用foreach循環(huán)來遍歷數(shù)組元素// 其中book將會自動迭代每個數(shù)組元素for( String book : books){System.out.println(book);}} }使用foreach循環(huán)迭代數(shù)組元素時,并不能改變數(shù)組元素的值,因此不要對foreach的循環(huán)變量繼續(xù)賦值。
深入數(shù)組
內(nèi)存中的數(shù)組
實際的數(shù)組對象被存儲在堆(heap)內(nèi)存中;如果引用該數(shù)組對象的數(shù)組引用變量是一個局部變量,那么它被存儲在棧(stack)內(nèi)存中。
如果需要訪問4.2所示堆內(nèi)存中的數(shù)組元素,則程序中只能通過p[index]的形式實現(xiàn)。也就是說,數(shù)組引用變量是訪問堆內(nèi)存中數(shù)組元素的根本方式。
當一個方法執(zhí)行時,每個方法都會建立自己的內(nèi)存棧,在這個方法內(nèi)定義的變量將會逐個放入這塊棧內(nèi)存里,隨著方法的執(zhí)行結束,這個方法的內(nèi)存棧也將自然銷毀。因此,所有在方法中定義的局部變量都是放在棧內(nèi)存中的;在程序中創(chuàng)建一個對象時,這個對象將被保存到運行時數(shù)據(jù)區(qū)中,以便反復利用(因為對象的創(chuàng)建成本通常較大),這個運行時數(shù)據(jù)區(qū)就是堆內(nèi)存。堆內(nèi)存中的對象不會隨方法的結束而銷毀,即使方法結束后,這個對象還可能被另一個引用變量所引用(在方法的參數(shù)傳遞時很常見),則這個對象依然不會被銷毀。只有當一個對象沒有任何引用變量引用它時,系統(tǒng)的垃圾回收器才會在合適的時候回收它。
如果堆內(nèi)存中數(shù)組不再有引用變量指向自己,則這個數(shù)組將成為垃圾,該數(shù)組所占的內(nèi)存將會被系統(tǒng)的垃圾回收機制回收。因此,為了讓垃圾回收機制回收一個數(shù)組所占的內(nèi)存空間,可以將該數(shù)組變量賦為null,也就切斷了數(shù)組引用變量和實際數(shù)組之間的引用關系,實際的數(shù)組也就成了垃圾。
基本類型數(shù)組的初始化
int[] iArr;iArr = new int[5];
for(int i = 0; i < iArr.length; i++) {iArr[i] = i + 10; }
引用類型數(shù)組的初始化
沒有多維數(shù)組
沒有多維數(shù)組——如果從數(shù)組底層的運行機制上來看。Java語言里的數(shù)值類型是引用類型,因此數(shù)組變量其實是一個引用,這個引用指向真實的數(shù)組內(nèi)存。數(shù)組元素的類型也可以是引用,如果數(shù)組元素的引用再次指向真實的數(shù)組內(nèi)存,這種情形看上去很像多維數(shù)組。
定義二維數(shù)組的語法: type[][] arrName; 它的實質(zhì)還是一維數(shù)組,只是其數(shù)組元素也是引用,數(shù)組元素保存的引用指向一維數(shù)組。
arrName = new type[length][];初始化多維數(shù)組時,可以只指定最左邊維的大小;當然,也可以一次指定每一堆的大小。
int[][] b = new int[3][4];
Java8增強的工具類Arrays
java.util.Arrays
int binarySearch(type[] a, type key) 使用二分法查詢key元素值在a數(shù)組中出現(xiàn)的索引;如果a數(shù)組不包含key元素值,則返回負數(shù)。調(diào)用該方法時要求數(shù)組中元素已經(jīng)按升序排列,這樣才能得到正確結果int binarySearch(type[] a, int fromIndex, int toIndex, type key) 只搜索fromIndex到toIndex索引的元素type[] copyOf(type[] original, int length) 將會把iriginal數(shù)組復制到一個新數(shù)組,其中l(wèi)ength是新數(shù)組的長度。如果length小于original數(shù)組的長度,則新數(shù)組就是原數(shù)組的前面length個元素;如果length大于original數(shù)組的長度,則新數(shù)組的前面元素就是原數(shù)組的所有元素,后面補充0(數(shù)值類型)、false(布爾類型)或null(引用類型)。type[] copyOfRange(type[] original, int fromIndex, int toIndex) 只負責original數(shù)組的fromIndex索引到toIndex索引的元素boolean equals(type[] a, type[] a2) 如果a數(shù)組和a2數(shù)組的長度相等,而且a數(shù)組和a2數(shù)組的數(shù)組元素也一一相同,該方法將返回truevoid fill(type[] a, type val) 將會把a數(shù)組的所有元素賦值為valvoid fill(type[] a, int fromIndex, int toIndex, type val) 僅僅將a數(shù)組的fromIndex(包括)到toIndex索引(不包括)的數(shù)組元素賦值為valvoid sort(type[] a) 對a數(shù)組的數(shù)組元素繼續(xù)排序void sort(type[] a, int fromIndex, int toIndex) 僅僅對a數(shù)組的fromIndex索引到toIndex索引的元素進行排序String toString(type[] a) 將一個數(shù)組轉換成一個字符串。該方法按順序把多個數(shù)組元素連綴在一起,多個數(shù)組元素使用英文逗號(,)和空格隔開。----------------------------- System類: static void arraycopy(Object src, int srcPos, Object dest, int desPos, int length)方法,該方法可以將src數(shù)組里的元素值賦給dest數(shù)組的元素,其中srcPos指定從src數(shù)組的第幾個元素開始賦值,length參數(shù)指定將src數(shù)組的多少個元素值賦給dest數(shù)組的元素。----------------------------- Arrays類增加了一些工具方法,這些工具方法可以充分利用多CPU并行的能力來提高設值、排序的性能。 void parallelPrefix(xxx[] array, XxxBinaryOperator op) 使用op參數(shù)指定的計算公式計算得到的結果作為新的元素。op計算公式包括left、right兩個形參,其中l(wèi)eft代表數(shù)組中前一個索引處的元素,right代表數(shù)組中當前索引處的元素,當計算第一個新數(shù)組元素時,left的值默認為1。void parallelPrefix(xxx[] array, int fromIndex, int toIndex, XxxBinaryOperator op)void setAll(xxx[] array, IntToXxxFunction generator) 使用指定的生成器generator為所有數(shù)組元素設置值,該生成器控制數(shù)組元素的值的生成算法。void parallelSetAll(xxx[] array, IntToXxxFunction generator) 功能與上一個方法相同,只是該方法增加了并行能力,可以利用多CPU并行來提高性能。void parallelSort(xxx[] a) 該方法與sort()方法相似,只是增加了并行能力,可以利用多CPU并行來提高性能。void parallelSort(xxx[] array, int fromIndex, int toIndex)Spliterator.OfXxx spliterator(xxx[] array) 將該數(shù)組的所有元素轉換成對應的Spliterator對象。Spliterator.OfXxx spliterator(xxx[] array, int startInclusive, int endExclusive) 該方法僅轉換startInclusive到endInclusive索引的元素。XxxStream stream(xxx[] array) 該方法將數(shù)組轉換為Stream,Stream是Java8新增的流式編程的API。XxxStream stream(xxx[] array, int startInclusive, int endExclusive) 所有以parallel開頭的方法都表示該方法可以利用CPU并行的能力來提高性能。上面方法中的xxx代表不同的數(shù)據(jù)類型,比如處理int[]型數(shù)組時應將xxx換成int,處理long[]型數(shù)組時應將xxx換成long。本章練習
1.
public class NineXNine {public static void main(String[] args) {for (int i = 1; i < 10; i++) {for (int j = 1; j <= i; j++) {System.out.print(i+" x "+j+" = " + i*j);if (j != i) {System.out.print(" , ");}}System.out.println();}} }2.
public class Triangle {public static void main(String[] args) {Tri tri = new Tri();tri.Tri(4);} }class Tri{public void Tri(int n) {int i;for(i = 1; i <= n; i++){for (int j1 = 1; j1 <= n-i; j1++) {System.out.print(" ");}for (int k = 1; k <= 2*i - 1; k++) {System.out.print("*");}System.out.println();}}}3.
public class MathDraw{public static void main(String[] args){//調(diào)用繪圖函數(shù),參數(shù)是圓的半徑paint(8);}public static void paint(int r){//假定圓心在坐標(r,r)處int x = 0;//x的坐標開始int y = 0;//y的坐標開始int c = 0;//中間空格數(shù)int z = 2;//每行遞減量,步長設為2是為了調(diào)節(jié)屏幕縱橫比。for (int i = 0; i <= r*2; i += z){//獲取畫*點的坐標的x值x = getX(r, y);//先畫y值上左邊的*System.out.print(getSpace(x)+"*");c = (r-x)*2;//以圓心對應輸出空格//再畫該y值上右邊的*System.out.println(getSpace(c)+"*");//每次y值遞減y += z;}}public static int getX(int r, int y){//取直角三角形長邊長int h = y - r;//求直角三角形短邊長double l = Math.sqrt((r*r)-(h*h));//取x值,Math.round()返回最接近的整數(shù)return (int) Math.round(r-l);}public static String getSpace(int i){String s = "";for(int j = 0; j < i; j++){s += " ";}return s;}}5
import java.text.DecimalFormat;/*** Program Name: ConvertRMB <br />* Description: 將浮點金額轉換成人民幣讀法,精確到分,例如輸入:1006.33,輸出:壹仟零陸元叁角叁分 <br /> 最大支持值到9999999999999998 <br />* Date: 2011-10-19 <br />* @author ChiAlvin.Chan*/public class NumToRmb {/*** @param d 需要轉換的金額* @return 返回大寫金額字符串(String)*/public static String convert(double d) {String[] numTables = new String[]{"零", "壹", "貳", "叁", "肆", "伍", "陸", "柒", "捌", "玖"};String[] unitTables = new String[]{"分", "角"};String[] levelTables = new String[]{"萬", "億"};String[] mulTables = new String[]{"", "拾", "佰", "仟"};StringBuffer result = new StringBuffer();int index = -1;// 將數(shù)字格式化為xxxx.xxDecimalFormat df = new DecimalFormat();df.setGroupingSize(4);df.setMinimumFractionDigits(2);String strFormat = df.format(d);// 拆分整數(shù)部分和小數(shù)部分StringBuffer intPart = new StringBuffer(strFormat.substring(0, strFormat.length()-3));StringBuffer decimalPart = new StringBuffer(strFormat.substring(intPart.length()+1, strFormat.length()));// 處理小數(shù)部分decimalPart.reverse();for(int i=0; i<decimalPart.length(); i++) {result.append(unitTables[i%2]);result.append(numTables[Character.getNumericValue(decimalPart.charAt(i))]);}// 處理整數(shù)部分result.append("元");intPart.reverse();int level = 0;for(int i=0; i<intPart.length(); i++) {if(intPart.charAt(i) != ',') {result.append(mulTables[i%5]);result.append(numTables[Character.getNumericValue(intPart.charAt(i))]);} else {result.append(levelTables[level]);level = ++level % 2;}}result.reverse();// 處理多余的零while((index = result.indexOf("零分")) != -1){ result.deleteCharAt(index+1); };while((index = result.indexOf("零角")) != -1){ result.deleteCharAt(index+1); };while((index = result.indexOf("零拾")) != -1){ result.deleteCharAt(index+1); };while((index = result.indexOf("零佰")) != -1){ result.deleteCharAt(index+1); };while((index = result.indexOf("零仟")) != -1){ result.deleteCharAt(index+1); };// 沒有小數(shù)部分while((index = result.indexOf("元零零")) != -1) {result.delete(index+1, index+3);result.append("整");};while((index = result.indexOf("零零")) != -1){ result.deleteCharAt(index); };while((index = result.indexOf("零元")) != -1) {result.deleteCharAt(index);};while((index = result.indexOf("零萬")) != -1) {result.deleteCharAt(index);};while((index = result.indexOf("零億")) != -1) {result.deleteCharAt(index);};while((index = result.indexOf("億萬")) != -1) {result.deleteCharAt(index+1);};// 沒有分位while((index = result.indexOf("角零")) != -1){ result.deleteCharAt(index+1); };// 只有分位while((index = result.indexOf("元零")) != -1 && index == 0){ result.delete(index, index+2); };// 只有小數(shù)位while((index = result.indexOf("元")) != -1 && index == 0){ result.deleteCharAt(index); };// 零元while((index = result.indexOf("整")) != -1 && index == 0){ result.replace(index, index+2, "零元"); };return result.toString();}public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println(NumToRmb.convert(1006.33));}}總結
以上是生活随笔為你收集整理的Java 流程控制与数组的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IP伪造与防范
- 下一篇: Java刷题知识点之方法覆盖(方法重写)