《Java8學習筆記》讀書筆記(五)

第4章 認識對象

學習目標
? 區(qū)分基本類型與對象類型
? 了解對象與引用的關系
? 從打包器認識對象
? 以對象觀點看待數(shù)組
? 認識字符串的特性

4.1 類與對象

第3章講的都是基本類型虹脯,這一章開始講對象類型艾船。在Java中一切皆對象(Object)凌蔬,要產生對象必須先寫類(Class)碉钠,類是對象的模版,對象是類的實例(Instance)

4.1.1 定義類

一個類就是一個模版鳍征,它包括了所有的屬性和方法,就象設計師手上的設計圖紙一樣,如果我們需要設計一個大黃鴨遭庶,那么我們首先會繪制一個大黃鴨的設計圖,上面定義了大黃鴨的大小稠屠、顏色等峦睡,我們會根據(jù)設計圖制作出實際的大黃鴨,每個大黃鴨都是同一個款式权埠,但會擁有自己的大小榨了,顏色。


圖4.1 大黃鴨設計攘蔽、制作
如果我們要設計的就是一個關于大黃鴨的設計的軟件龙屉,那如何使用Java來編寫呢?首先就要在程序中定義類满俗,這相當于圖4.1中大黃鴨的設計圖:

class BigDuke{
    String color;
    int size;
}

類定義時使用class關鍵字转捕,名稱使用BigDuck,相當于為大黃鴨的設計圖取名叫BigDuck唆垃,大黃鴨的顏色用字符串表示五芝,也就是color變量,可存儲”深黃”辕万,”淺黃”枢步,”大黃”等。
大黃鴨的尺寸會是’大’渐尿,’中’醉途,’小’,所以使用了char類型砖茸。如果要在程序中隘擎,利用BigDuck在程序內建立實例,就要使用new關鍵字凉夯。例如:

new BigDuck();

在對象術語中嵌屎,這叫做實例化一個對象推正。如果要有個標簽,和這個對象綁定宝惰,可以這樣聲明:

BigDuck bd;

是不是很象前面我們聲明基本變量的形式植榕?不過Java專門為這種指向對象的“變量”取了個術語,叫“引用”(Reference Name)尼夺。如果要將bd綁到新建的對象上尊残,可以使用“=”賦值,在Java術語中淤堵,叫“將bd引用至實例化對象”寝衫。如:

BigDuck bd=new BigDuck();

圖4.2 class、new拐邪、=等語法對應
提示:對象(Object)與實例(Instance)在Java中幾乎是等義的名詞慰毅,本書中就視為相同意義。
在BigDuck類中扎阶,定義了color與size兩個變量汹胃,以Java的術語來說,叫作定義兩個屬性(Field)成員东臀,或叫定義兩個成員變量着饥,這表示每個新建的BigDuck實例中都能擁有各自不同的color值與size值。(默然說話:其實簡單說惰赋,就是類是一個模版宰掉,它定義的類別應該具有的屬性,但沒有值赁濒,而實例對象則會具備相同的屬性轨奄,且每個屬性可以有不同的值。比如人類可以定義膚色與身高拒炎,然后每個人類的實例可以擁有不同的膚色值與身高值挪拟。

class BigDuck{
    String color;
    char size;
}
/**
 * 說明類和對象關系的代碼示例
 * 文件:ObjectTest.java
 * @author mouyo
 */
public class ObjectTest {
    public static void main(String[] args) {
        //實例化大黃鴨對象
        BigDuck foodDuck=new BigDuck();
        BigDuck lakeDuck=new BigDuck();
        
        //為每個大黃鴨對象的屬性賦值
        foodDuck.color="淺黃";
        foodDuck.size='小';
        lakeDuck.color="深黃";
        lakeDuck.size='大';
        
        //顯示每個大黃鴨對象的各自屬性值
        System.out.println("黃鴨飯:"+foodDuck.color+","+foodDuck.size);
        System.out.println("湖中大黃鴨:"+lakeDuck.color+","+lakeDuck.size);
    }
}

在這個ObjectTest.java中,定義了兩個類枝冀,一個是公開(public)的ObjectTest類,Java規(guī)定耘子,公開(public)的類名必須與文件一致果漾。另一個是非公開的BigDuck。
提示:只要有類定義谷誓,編譯程序就會產生一個.class文件绒障。上例中會產生ObjectTest.class和BigDuck.class兩個文件
程序中實例化了兩個BigDuck對象,并分別聲明了foodDuck與lakeDuck兩個引用變量捍歪,接著指定了foodDuck綁定的對象所擁有的color和size分別賦值為”淺黃”和’小’户辱,而lakeDuck綁定的對象所擁有的color和size分別賦值為”深黃”和’大’鸵钝。最后分別顯示foodDuck與lakeDuck各自擁有的屬性值:

run:
黃鴨飯:淺黃,小
湖中大黃鴨:深黃,大
成功構建 (總時間: 0 秒)

執(zhí)行結果如上,可以看出來庐镐,每個對象都擁有自己的數(shù)據(jù)恩商,它們是相互獨立,互不影響的必逆。(默然說話:這也就在提醒我們怠堪,當我們進行屬性賦值的時候,除了要關心屬性的值之外名眉,還要關心被賦值的屬性是哪個對象粟矿,如果搞錯了對象,那值也就是不對的了损拢。
觀察為每個大黃鴨對象的屬性賦值的那段代碼陌粹,你會發(fā)現(xiàn)它們雖然是給不同的對象賦值,但代碼的書寫基本是一樣的福压。只要是一樣的代碼掏秩,我們就可以進行模版化,讓這些代碼只寫一遍隧膏。這里我們可以使用構造方法哗讥。構造方法是與類名同名的方法,它沒有返回值胞枕。

public class BigDuck2 {
   String color;
   char size;
   BigDuck2(String color,char size){//構造方法
       this.color=color;//將參數(shù)color指定給color屬性
       this.size=size;
   }
   
    public static void main(String[] args) {
        BigDuck2 foodDuck=new BigDuck2("淺黃",'小');//使用指定構造方法建立對象
        BigDuck2 lakeDuck=new BigDuck2("深黃",'大');
        
        //顯示每個大黃鴨對象的各自屬性值
        System.out.println("黃鴨飯:"+foodDuck.color+","+foodDuck.size);
        System.out.println("湖中大黃鴨:"+lakeDuck.color+","+lakeDuck.size);
    }
}

在這個例子中杆煞,定義新建對象時,必須傳入兩個參數(shù)給String類型的color與char類型size參數(shù)腐泻,而構造方法中决乎,由于color參數(shù)與color屬性名相同,你不可以直接寫color=color派桩,而要寫成this.color=color构诚。
在實際使用new創(chuàng)建對象時,就可以直接傳入字符串與字符铆惑,分別代表BigDuck實例的color與size值范嘱,執(zhí)行結果與上個例子相同。

4.1.2 使用標準類

第一章已經講過员魏,Java Se提供了標準API,這些API就是由許多類組成丑蛤,你可以直接取用這些標準類,省去自己打造基礎的需求撕阎。下面舉兩個基本的標準類:java.util.Scannerjava.math.BigDecimal受裹。
1.使用java.util.Scanner
目前為止的程序例子都很無聊,變量值都是寫死的,沒有辦法接受用戶的輸入棉饶。如果要在命令行模式下取得用戶輸入厦章,我們就可以使用java.util.Scanner

package cn.com.speakermore.ch04;

import java.util.Random;
import java.util.Scanner;//導入標準API中的Scanner類

/**
 * 猜數(shù)
 * @author mouyo
 */
public class Guess {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);//創(chuàng)建Scanner對象
        int number=new Random().nextInt(10);
        int guess;
        
        do{
            System.out.print("猜數(shù)(0~9)");
            guess=input.nextInt();//獲得用戶輸入的整型數(shù)
        }while(guess!=number);
        System.out.println("恭喜照藻!猜對了袜啃!");
    }
}

由于我們不想每次都輸入java.util.Scanner,所以一開始就使用import告訴編譯器:“我需要使用java.util.Scanner岩梳,請幫我導入囊骤。”在實例化(new)Scanner對象時冀值,必須傳入System.in對象也物,它是一個java.io.InputStream流對象(默然說話:關于這些內容,第10章會詳細介紹列疗,你現(xiàn)在就當做烏龜?shù)钠ü伞?guī)定——來照著寫就可以了)滑蚯。
接下來就可以很簡單的通過Scanner的對象(名字叫input)來獲得鍵盤的輸入了。大家完全不用管它是怎么獲得鍵盤輸入的抵栈,反正就是能獲得告材。(默然說話:這就是面向對象里面的一個概念:封裝。舉個生活中的例子:你只要懂得打開水龍頭古劲,就可以得到水斥赋,而完全不用去關心水怎么是從水龍頭里流出來的。忽略細節(jié)产艾,可以讓我們更專心的做自己想要去完成的事情疤剑,而不用啥都操心,這就是封裝闷堡。后面的相關章節(jié)還會詳細闡述隘膘。
ScannernextInt()方法會查看鍵盤輸入的是不是數(shù)字,如果是數(shù)字就會接收杠览。Scanner對每個基本類型弯菊,都會有個對應的nextXxx()方法,如nextByte()踱阿、nextShort()管钳、nextLong()、nextFloat()软舌、nextDouble()才漆、nextBoolean()等,如果要取字符串葫隙,則使用next()栽烂,如果是取一行字符串躏仇,則使用nextLine()(以換行分隔)恋脚。

提示:包是java管理類的一種方式腺办,后面相關內容會介紹。包名以java開頭的類糟描,都是標準API提供的類怀喉。

2.使用java.math.BigDecimal
第2章介紹基本類型的時候有個問題:1.0-0.8的結果是多少?答案肯定不是0.2船响,而是0.19999999999999996躬拢。為什么?java的bug?肯定不是见间,因為你用其他的語言來算這個算式也會得到同樣的結果聊闯。
簡單來說,java遵守IEEE754浮點數(shù)運算規(guī)范米诉,使用分數(shù)與指數(shù)來表示浮點數(shù)菱蔬。例如0.5是使用1/2來表示,0.75是使用1/2+1/4來表示史侣,而0.1會使用1/16+1/32+1/256+…無限循環(huán)下去拴泌,無法精確表示。因而造成運算上的誤差惊橱。
再來舉個例子蚪腐,你覺得下面的程序片段會顯示什么結果?

        double a=0.1;
        double b=0.1;
        double c=0.1;
        
        if((a+b+c)==0.3){
            System.out.println("等于0.3");
        }else{
            System.out.println("不等于0.3");
        }

由于浮點數(shù)誤差的關系税朴,結果是顯示“不等于0.3”回季。類似的例子還有很多,結論就是掉房,如果要求精確度茧跋,那就要小心地使用浮點數(shù),而且別用==直接比較浮點數(shù)運算結果卓囚。
那么要怎么辦能得到更好的精確度瘾杭?可以使用java.math.BigDecimal類瓢宦。

import java.math.BigDecimal;
/**
 *DecimalDemo.java
 * @author mouyo
 */

public class DecimalDemo {
    public static void main(String[] args) {
        BigDecimal a=new BigDecimal("1.0");
        BigDecimal b=new BigDecimal("0.8");
        BigDecimal result=a.subtract(b);
        System.out.println(result);
        System.out.println(1.0-0.8);
    }
}

創(chuàng)建BigDecimal的方法之一是使用字符串超棺,BigDecimal在創(chuàng)建時會分析字符串纸泄,以默認精度進行接下來的運算受楼。BigDecimal提供有plus()懦鼠、substract()谚殊、multiply()偎蘸、divide()等方法聚蝶,可以進行加篡殷、減钝吮、乘、除等運算,這些方法都會返回代表運算結果的BigDecimal奇瘦。
上面的例子可以看到0.2的結果棘催,再來看利用BigDecimal比較相等的例子。

import java.math.BigDecimal;

/**
 *DecimalDemo2.java
 * @author mouyo
 */
public class DecimalDemo2 {
    public static void main(String[] args) {
        BigDecimal a=new BigDecimal("0.1");
        BigDecimal b=new BigDecimal("0.1");
        BigDecimal c=new BigDecimal("0.1");
        BigDecimal result=new BigDecimal("0.3");
        
        if(a.add(b).add(c).equals(result)){
            System.out.println("等于0.3");
        }else{
            System.out.println("不等于0.3");
        }
    }
}

由于BigDecimaladd()方法都會返回代表運算結果的BigDecimal耳标,所以就直接利用返回再次add()醇坝。最后再調用equals()方法比較相等。最后的結果是等于0.3次坡。

4.1.3 對象指定與相等性

在上一例中呼猪,比較兩個BigDecimal是否相等,是使用equals()方法而非使用==運算符砸琅,為什么宋距?前面說過,在Java中有兩大類型系統(tǒng)症脂,基本類型和引用類型乡革,基本類型把值直接放到變量中,而引用類型是把對象的內存地址放入變量中摊腋。
當使用=(默然說話:記追邪妗!這個不是等號兴蒸,是賦值號视粮,用來把一個值放到某個變量中!)給基本變量賦值時橙凳,就是把值直接放入了變量中蕾殴,而引用類型變量賦值時,放入的是一個對象的所在位置的地址岛啸。正因為如此钓觉,當使用==進行比較時,基本變量就是比較了值是否相等(默然說話:因為基本變量就保存了一個值呀!)而引用類型變量比較的卻是內存位置是否相等(因為引用類型變量保存的是地址呀坚踩!)荡灾。
這是基本類型變量的代碼與示例圖,記住瞬铸,基本類型保存的是值批幌!

        int a=10;
        int b=10;
        int c=a;
        System.out.println(a==b);
        System.out.println(a==c);

圖4.3 基本變量的賦值與比較相等的結果


圖4.4 基本變量的賦值與比較相等的原理
這是引用類型變量的代碼與示例圖,記住嗓节,引用類型保存的是地址荧缘!
BigDecimal a=new BigDecimal("0.1");
BigDecimal b=new BigDecimal("0.1");
BigDecimal c=a;
System.out.println(a==b);
System.out.println(a==c);

圖4.5 引用類型變量的賦值與比較相等

圖4.6 引用類型變量的比較相等結果
使用==比較的就是變量里所保存的值是否相等,由于引用類型保存的值是對象的內存地址拦宣,所以比較兩個引用型變量相等截粗,就是比較兩個引用變量所引用的對象是不是同一個(默然說話:內存地址相同信姓,就是同一個變量,因為不可能在同一個內存地址中放兩個不同的對象绸罗。)财破,如果我們想要的結果是兩個對象的內容是不是一樣,我們需要使用equals()方法从诲。(默然說話:上面的程序中可以看到兩個對象都裝著“0.1”這個數(shù),所以如果我們是要兩個對象裝的內容是不是一樣靡羡,是不能使用==來比較的系洛,因為它比較的是地址
提示:其實從內存的實際運作來看,=與==對于基本類型變量與引用類型變量的作用并沒有不同略步,只是因為它們所保存的值的意義不一樣描扯,才造成了這一區(qū)別。

4.2 基本類型包裝類

基本類型long趟薄、int绽诚、double、float杭煎、boolean等恩够,在J2SE5.0之前必須手動使用Long、Integer羡铲、Double蜂桶、Float、Boolean等打包為對象也切,才能當作對象來操作扑媚。5.0之后開始自動打包了。

4.2.1 包裝基本類型

Java的基本類型在于效率雷恃,但更多的時候疆股,會使用類建立實例,因為對象本身可以提供更多信息倒槐,更多方便的操作旬痹。可以使用Long讨越、Integer唱凯、Double、Float谎痢、Boolean磕昼、Byte等類來包裝(Wrap)基本類型。
Long节猿、Integer票从、Double等類就是所謂的包裝類(Wrapper)漫雕,正如此名稱所示,這些類主要目的就是提供對象實例作為“殼”峰鄙,將基本類型包裝在對象中浸间,就像是將基本類型當作對象操作。

/**
 *  IntegerDemo.java
 * @author mouyo
 */
public class IntegerDemo {
    public static void main(String[] args) {
        //基本類型
        int data1=10;
        int data2=10;
        //包裝類型
        Integer wrapper1=new Integer(data1);
        Integer wrapper2=new Integer(data2);
        //基本類型除法吟榴,只能得到整數(shù)部分魁蒜,小數(shù)被舍棄
        System.out.println(data1/3);
        //使用包裝類的方法把整數(shù)轉為小數(shù),得到了有小數(shù)的結果
        System.out.println(wrapper1.doubleValue()/3);
        //使用包裝類提供的方法進行比較吩翻,得到更多的信息
        System.out.println(wrapper2.compareTo(wrapper2));
    }
}

包裝類都放在java.lang包中兜看,這個包是java編譯器默認會導入的包,所以不需要import語句來顯示導入狭瞎。包裝一個基本類型就是new出包裝類细移,然后將基本類型傳給包裝類就可以了。
基本數(shù)據(jù)類型如果都是整型熊锭,那最后的計算結果也會是整形弧轧。
如果我們期望得到小數(shù)的結果,那么可以使用包裝類的轉換方法來得到一個小數(shù)碗殷,然后計算機在運算時會自動類型轉換為小數(shù)后再做計算精绎,最后的結果就也是小數(shù)(默然說話:其實我們平時寫程序時,是直接把整型數(shù)寫成小數(shù)锌妻。比如10/3.0捺典,這樣的結果就會是小數(shù)了。)从祝。
Integer提供compareTo()方法襟己,可與另一個Integer對象比較,如果相同就返回0牍陌,如果小于傳入的對象就返回-1擎浴。否則就是1。而==和!=只能得到很少的信息毒涧。

4.2.2 自動裝箱贮预、拆箱

除了使用new來包裝之外,從J2SE5.0之后提供了自動裝箱功能契讲》峦蹋可以這樣包裝基本類型:

Integer wrapper=10;

編譯程序會自動判斷是否能進行自動裝箱,在上例如你的wrapper會被賦值為一個Integer對象捡偏。其他基本類型也是一樣的唤冈。改寫下上面的代碼:

Integer data1=10;
Integer data2=20;
System.out.println(data1.doubleValue() / 3);
System.out.println(data1.compareTo(data2));

程序看上去簡潔很多,data1和data2在運行時會自動裝箱Integer對象银伟。自動裝箱還可以這樣用:

int i=0;
Integer wrapper=i;

也可以使用更一般化的Number來自動裝箱:

Number num=3.11f;

3.11f會先被自動裝箱為Float你虹,然后引用給num绘搞。
Java SE 5.0開始,還可以進行自動拆箱傅物,也就是把包裝類自動取值賦給基本類型變量夯辖。如:

Integer wrapper=10;//自動裝箱
int a=wrapper;//自動拆箱

在運算時,也可以進行自動裝箱與拆箱董饰,如:

Integer a=10;
System.out.println(i+10);
System.out.println(i++);

4.2.3 自動裝箱蒿褂、拆箱的內幕

所謂自動裝箱與拆箱其實只是編譯器幫我們做了本來是我們需要自己做的事情。編譯器在編譯時會根據(jù)我們所寫的代碼來決定是否進行裝箱或拆箱卒暂。例如下面的代碼:

Integer number=100;

在Oracle的JDK中 ,編譯程序會自動將代碼展開為:

Integer localInteger=Integer.valueOf(100);

但自動裝拆箱其實是有問題的啄栓,例如:

Integer a=null;
int j=i;

這段代碼在編譯的時候是不會報錯的,因為null是一個特殊對象介却,它可以指定給任何聲明的對象,表示沒有引用到任何的內存地址块茁,但是一旦執(zhí)行編譯出的代碼齿坷,就會報錯,因為編譯后的代碼是這樣的:

Object localObject=null;
int i=localObject.intValue();

這里由于localObject對象被賦值為空数焊,而代表沒有任何的內存位置永淌,所以也就不可能執(zhí)行第二句調用intValue()方法,此時計算機就會報錯NullPointerException(空指針異常佩耳,有的教科書或老師又把它叫做空點異常)遂蛀。表示你想調用一段根本不在內存里存在的代碼。
除了有這方面的bug之外干厚,還有一些稀奇古怪的現(xiàn)象李滴。比如下面的代碼:

/**
 *  Boxing.java
 * @author mouyo
 */
public class Boxing {
    public static void main(String[] args) {
        Integer i1=100;
        Integer i2=100;
        if(i1==i2){
            System.out.println("相等");
        }else{
            System.out.println("不相等");
        }
    }
}

這個代碼沒問題,結果是相等蛮瞄。


圖4.7 結果相等
可是所坯,我們只要改一下,象下面這樣:

package cn.com.speakermore.ch04;

/**
 *  Boxing.java
 * @author mouyo
 */
public class Boxing {
    public static void main(String[] args) {
        Integer i1=200;
        Integer i2=200;
        if(i1==i2){
            System.out.println("相等");
        }else{
            System.out.println("不相等");
        }
    }
}

能看出來改了哪里么挂捅?對芹助,只是把100換成了200,運行之后的結果卻變成了不相等闲先。


圖4.8 200之后的結果是不相等状土。
為何是這樣的結果,這是因為在Integer的自動裝箱過程中伺糠,它使用了valueOf()方法蒙谓,而valueOf()方法會建立一個緩存,緩存那些小于128的整數(shù)训桶。這樣彼乌,當我們的值小于128時泻肯,值相同,對象就是相同的慰照,但是一旦大于等于128灶挟,由于沒有緩存,雖然值是相同的毒租,但對象就會不一樣稚铣。用==比較時,自然就得到了不相等的結果墅垮。
所以惕医,結論還是前面已經討論過的,別使用==或!=來比較兩個對象的值是否相同(因為引用型數(shù)據(jù)類型都是比較的地址)算色,而要使用equals()方法抬伺。

4.3 數(shù)組對象

數(shù)組在Java中就是對象,所以前面介紹過的對象基本性質灾梦,在操作數(shù)組時也都要注意峡钓,如引用名的聲明、=指定的作用若河、==與!=的比較等能岩。

4.3.1 數(shù)組基礎

數(shù)組基本上是用來收集數(shù)據(jù),具有下標(index)的數(shù)據(jù)結構萧福,在Java中要聲明數(shù)組并初始值拉鹃,可以如下:

int[] score={88,87,99,67,77,81,86,55,46,78};

這段代碼創(chuàng)建一個數(shù)組,因為使用int[]聲明鲫忍,所以會在內存中分配長度為10的int連續(xù)空間膏燕,每個空間依次存儲了大括號中的整數(shù),每個整數(shù)都用一個下標來標識悟民,下標從0開始煌寇,所以10個長度的數(shù)組,下標最大就只到9逾雄。如果你使用了10或以上的數(shù)字作下標阀溶,就會拋出ArrayIndexOutOfBoundException(數(shù)組下標越界異常)。
數(shù)組使用下標來獲得每一個數(shù)據(jù)鸦泳,重點就是可以很方便的和循環(huán)結合银锻,用很少的代碼對大量數(shù)據(jù)進行批量處理:

/**
 * Score.java
 * @author mouyo
 */
public class Score {
    public static void main(String[] args) {
        int[] score={88,87,99,67,77,81,86,55,46,78};
        for (int i = 0; i < score.length; i++) {
            System.out.println("學生分數(shù):"+score[i]);
        }
    }
}

在聲明的數(shù)組名稱旁加上[]并指定下標,就可以取得對應值做鹰,上例從i為0-9击纬,逐一取出值并顯示出來。


圖4.9 10個學生分數(shù)的顯示
在Java中數(shù)組是對象钾麸,而不是單純的數(shù)據(jù)集合更振,數(shù)組的length屬性可以取得數(shù)組長度炕桨。也就是數(shù)組的元素個數(shù)。
其實上面這個程序可以使用更簡單的方式來編寫肯腕,因為是順序取到數(shù)組中每一個值献宫,所以我們可以使用增強式for循環(huán),這是從JDK5開始出現(xiàn)的更方便的for循環(huán)实撒,我基本是強烈推薦姊途,在需要遍歷一個數(shù)組的時候都使用增強式for循環(huán)。

for (int score:scores ) {
   System.out.println("學生分數(shù):"+score);
}

這個程序片段會取得scores數(shù)組第一個元素知态,指定給score變量后執(zhí)行循環(huán)體捷兰,接著取得scores中第二個元素,指定給score變量后執(zhí)行循環(huán)體负敏。依此類推贡茅,直到scores數(shù)組中所有元素都訪問完為止。將這段for循環(huán)片段取代Score類中的for循環(huán)其做,執(zhí)行結果相同顶考。實際上,增強式for循環(huán)也是Java提供的方便功能庶柿。
如果要給數(shù)組的某個元素賦值村怪,也是要通過下標秽浇。例如:

scores[3]=86;
System.out.println(scores[3]);

上面這個程序片段將數(shù)組中第4個元素(因為下標從0開始浮庐,下標3就是第4個元素)指定86,所以會顯示86柬焕,所以會顯示86的結果审残。
一維數(shù)組使用一個下標存取數(shù)組元素,你也可以聲明二維數(shù)組斑举,二維數(shù)組使用兩個下標存取數(shù)組元素搅轿。例如,聲明數(shù)組來儲存XY坐標位置要放的值富玷。

/**
 * XY.java
 * @author mouyo
 */
public class XY {
    public static void main(String[] args) {
        int[][] cords={
            {1,2,3},
            {4,5,6}
        };//聲明二維數(shù)組并賦值初始值
        for(int x=0;x<cords.length;x++){//獲得有幾行
            for(int y=0;y<cords[x].length;y++){//獲得每行有幾個元素
                System.out.print(cords[x][y]+"  ");
            }
            System.out.println("");
        }
    }
}

要聲明二維數(shù)組璧坟,就是在類型關鍵詞旁加上[][]。初學者暫時將二維數(shù)組看作是一個表格會比較容易理解赎懦,由于有兩個維度雀鹃,所以首先得通過cords.length得到有幾行,然后再使用cords[x].length獲得每行有幾個元素励两,之后再一個一個進行輸出黎茎。
二維數(shù)組有兩個下標,所以也要使用二重嵌套循環(huán)來完成取值遍歷的代碼当悔,同樣由于這里對下標并沒有特別需要傅瞻,所以也可以使用增強for循環(huán)來完成

       for(int[] row:cords){//獲得有幾行
            for(int value:row){//獲得每行幾個元素
                System.out.print(value+"  ");
            }
            System.out.println("");
        }

最后執(zhí)行結果相同踢代。


圖4.10 二維數(shù)組執(zhí)行結果
提示:如果是三維數(shù)組,就是在類型關鍵字后使用三個[]嗅骄,如果是四維就是四個[]胳挎。依此類推。不過基本上是用不到如此復雜的維度掸读,現(xiàn)代編程通常一維就足夠了串远,二維都基本上不用的。

4.3.2 操作數(shù)組對象

前面都是知道元素值來建立數(shù)組的例子儿惫,如果事先不知道元素值澡罚,只知道元素個數(shù),那可以使用new關鍵字指定長度的方式創(chuàng)建數(shù)組肾请。例如:

int[] scores=new int[5];
數(shù)據(jù)類型 初始值
byte 0
short 0
int 0
long 0L
float 0.0F
double 0.0
char \u0000(即’’)
boolean false
null

在Java中只要看到new留搔,就一定是創(chuàng)建對象(默然說話:計算機的實際操作是劃分一塊內存空間供對象使用),這個語法其實已經說明數(shù)組就是一個對象铛铁。使用new創(chuàng)建數(shù)組之后隔显,數(shù)組中每個元素都會被初始化,如表4.1所示:
表4.1 數(shù)組元素初始值

數(shù)據(jù)類型 初始值
byte 0
short 0
int 0
long 0L
float 0.0F
double 0.0
char \u0000(即’’)
boolean false
null

如果默認值不符合你的需求饵逐,可以使用java.util.Arrays的fill()方法來設定新建數(shù)組的元素值括眠。例如,每個學生的成績默認60分:

import java.util.Arrays;

/**
 * Score2.java
 * @author mouyong
 */
public class Score2 {
    public static void main(String[] args) {
        int[] scores=new int[10];
        System.out.println("默認初始值");
        for(int score:scores){
            System.out.print(score+"  ");
        }
        System.out.println("\n初始填充后");
        Arrays.fill(scores, 60);
         for(int score:scores){
            System.out.print(score+"  ");
        }
    }
}

執(zhí)行結果如下:


圖4.11學生分數(shù)數(shù)組的初始化值
數(shù)組既然是對象倍权,再加上我們講過掷豺,對象是根據(jù)類而建立的實例,那么代表數(shù)組的類定義在哪里呢薄声?答案是由JVM動態(tài)產生当船。你可以將int[]看作是類名稱,這樣默辨,根據(jù)int[]聲明的變量就是一個引用變量德频,那么下面這段代碼會是什么結果?

         int[] scores1={88,66,48,99,12,45,55,76};
         int[] scores2=scores1;
         
         scores2[0]=99;
         System.out.println(scores1[0]);

因為數(shù)組是對象缩幸,而scores1與scores2是引用名稱壹置,所以將scores1賦值給scores2的意思就是將scores1引用的對象內存地址賦值給scores2,所以兩個變量指向了同一塊內存表谊,那么钞护,當你通過scores2[0]對這個數(shù)組的第1個元素進行修改之后,scores1也能看到變化(默然說話:記住铃肯,因為它們的指向是同一個地址患亿,再想想前面給大家的引用變量聲明的動畫)。
所以最后的輸出scores1[0]的值也是99。
再來看前面提過的二維數(shù)組:

int[][] cords=new int[2][3];

這個語法其實是建立了一個int[][]類型的對象步藕,里面有2個int[]類型的對象惦界。這2個一維的數(shù)組對象的長度都是3。初始值為0咙冗。


圖4.12二維數(shù)組的對象引用示意
對沾歪,從上圖中我們可以得到一個結論,其實Java的二維數(shù)組根本不是一個表格雾消,所以Java完全可以建立一個不規(guī)則的數(shù)組灾搏。例如:

/**
 * IrregularArray.java
 * @author mouyo
 */
public class IrregularArray {
    public static void main(String[] args) {
        int[][] arr=new int[2][];//聲明arr對象為二維數(shù)組
        arr[0]=new int[]{1,2,3,4,5};//arr[0]是一個長度為5的一維數(shù)組
        arr[1]=new int[]{1,2,3};//arr[1]是一個長度為3的一維數(shù)組
        //從輸出可以看出來,第一個輸出了5個數(shù)立润,第二個輸出了3個數(shù)狂窑,并非一個表格
        for(int[] row:arr){
            for(int value:row){
                System.out.print(value+"  ");
            }
            System.out.println();
        }
        
    }
}

這個例子我們可以看到,在new一個二維數(shù)組時可以只寫最高維桑腮,而不用寫最后一個維度的數(shù)量泉哈。然后再給每個數(shù)組下標實例化不同的低維度數(shù)組。而具體的數(shù)值就放在最低維度指向的空間里破讨。(默然說話:我驚訝的發(fā)現(xiàn)丛晦,當寫了二維聲明之后诱贿,不能再使用直接初始化的語法了老虫,也就是說,不能寫成arr[0]={1魂那,2隙笆,3锌蓄,4,5}仲器,必須寫成arr[0]=new int[]{1煤率,2仰冠,3乏冀,4,5}洋只,可能是因為一開始聲明時沒有給出低維度的長度辆沦,所以必須重新對低維度劃分空間罷)。
當然识虚,其實這個初始化的代碼也可以寫為:

        int[][] arr={
            {1,2,3,4,5},
            {1,2,3}
        };

以上都是基本類型創(chuàng)建的數(shù)組肢扯,那么引用類型創(chuàng)建的數(shù)組會是什么樣的情況呢?首先看看如何用new關鍵字建立Integer數(shù)組:

Integer[] scores=new Integer[3];

看上去不過就是把int換成了類Integer而已担锤。那想想這個數(shù)組創(chuàng)建了幾個Integer對象呢蔚晨?錯誤!不是3個,而是一個Integer對象都沒有創(chuàng)建铭腕∫瘢回頭看表4.1,對象類型的默認值是null累舷。這里只創(chuàng)建出一個Integer[]對象浩考,它可以容納3個Integer對象,但是因為對象型的默認初始化值為null被盈,所以現(xiàn)在這三個對象都還沒有產生析孽。我們必須在給它們的每個下標都賦值時,才會有Integer對象產生只怎。

/**
 * IntegerArray.java
 * @author mouyong
 */
public class IntegerArray {
    public static void main(String[] args) {
        Integer[] scores=new Integer[3];
        System.out.println("僅實例化了數(shù)組之后袜瞬,數(shù)組中的初始化值:");
        for(Integer score:scores){
            System.out.println(score);
        }
        scores[0]=new Integer(98);
        scores[1]=new Integer(99);
        scores[2]=new Integer(87);
        
        System.out.println("實例化每個元素之后,數(shù)組中的元素值:");
         for(Integer score:scores){
            System.out.println(score);
        }
        
    }
}

代碼的執(zhí)行結果如下:


4.13對象類型的數(shù)組初始化
所以每次講對象類型數(shù)組身堡,我總是說吞滞,對象類型數(shù)組需要new兩次,一次是new出對象數(shù)組盾沫,另一次是new出一系列放在數(shù)組中的對象裁赠。
上面的代碼之所以這樣寫,主要是為了突出對象的特點赴精,其實JDK5.0之后有了自動裝箱和拆箱佩捞,所以數(shù)組元素賦值可以寫成這樣:

        scores[0]=98;
        scores[1]=99;
        scores[2]=87;

對象類型其實也可以使用大括號進行初始化,只是寫得要長些:

Integer[] scores={new Integer(98),new Integer(99),new Integer(87)};

同樣蕾哟,上面的寫法也是為了強調對象型需要先new一忱,JDK5.0之后有了自動裝箱和拆箱,所以也可以寫成這樣:

Integer[] scores={99,98,87};

4.3.3 數(shù)組復制

在知道了數(shù)組其實是一種對象谭确,你就要知道帘营,下面的代碼不是復制:

int[] scores1={88,66,48,99,12,45,55,76};
int[] scores2=scores1;

復制應該是出現(xiàn)兩個內容相同的對象,但這只是讓兩個變量指向了同一個對象逐哈,也就是對象只有一個芬迄,并沒有兩個。所以真正的復制應該是這樣的昂秃。

int[] scores1={88,66,48,99,12,45,55,76};
int[] scores2=new int[scores1.length];
for(int i=0;i<scores1.length;i++){
    scores2[i]=scores1[i];
}

這是自己使用循環(huán)來完成每一個值的復制禀梳,其實可以使用System.arraycopy()方法來直接完成這個過程,比我們用循環(huán)來得快:

int[] scores1={88,66,48,99,12,45,55,76};
int[] scores2=new int[scores1.length];
System.arraycopy(scores1,0,scores2,0,scores1.length);

System.arraycopy()有五個參數(shù)肠骆,分別是源數(shù)組算途,源數(shù)組開始下標,目標數(shù)組蚀腿,目標數(shù)組開始下標嘴瓤,復制長度。如果使用JDK6以上,還有個更方便的Arrays.copyOf()方法廓脆,你不用另行建立數(shù)組畏浆,Arrays.copyOf()會幫你創(chuàng)建:

import java.util.Arrays;

/**
 * CopyArray.java
 * @author mouyong
 */
public class CopyArray {
    public static void main(String[] args) {
        int[] scores1={88,81,75,68,79,95,93};
        int[] scores2=Arrays.copyOf(scores1, scores1.length);
        System.out.println("scores2數(shù)組的元素:");
        for(int score:scores2){
            System.out.print(score+"  ");
        }
        System.out.println("");
        scores2[0]=99;
        System.out.println("修改了scores2第1個元素之后,scores1的元素仍然不變");
        for(int score:scores1){
            System.out.print(score+"  ");
        }
    }
}

執(zhí)行結果如下所示:


圖4.14Arrays.copyOf()進行數(shù)組復制無需自行創(chuàng)建數(shù)組
Java中狞贱,數(shù)組一旦創(chuàng)建刻获,長度就是固定的,如果長度不夠瞎嬉,就只能創(chuàng)建新的數(shù)組蝎毡,將原來的內容復制到新數(shù)組中。如:

int[] scores1={88,81,75,68,79,95,93};
int[] scores2=Arrays.copyOf(scores1, scores1.length*2);
System.out.println("scores2數(shù)組的元素:");
for(int score:scores2){
    System.out.print(score+"  ");
}

Arrays.copyOf()的第二個參數(shù)就是指定新數(shù)組的長度氧枣。上面程序讓新創(chuàng)建的數(shù)組長度是原來數(shù)組長度的2倍沐兵,輸出時會看到增加部分元素的值均為默認值0。
無論是System.arraycopy()還是Arrays.copyOf()便监,用在類類型聲明的數(shù)值時扎谎,都是執(zhí)行淺層復制(默然說話:也就是說,如果你的數(shù)組元素是對象烧董,那么復制一個新的數(shù)組時毁靶,新數(shù)組還在引用原數(shù)組的對象,并不會把原數(shù)組的對象進行復制逊移!)预吆。如果真的要連同對象一同復制,你得自行操作胳泉,因為基本上只有自己才知道拐叉,每個對象復制時,有哪些屬性必須復制扇商。

4.4 字符串對象

在Java中凤瘦,字符串本質是打包字符數(shù)組的對象。它同樣也有屬性和方法案铺。不過在Java中基于效率的考慮蔬芥,給予字符串某些特別且必須注意的性質。

4.4.1 字符串基礎

由字符組成的文字符號稱為字符串红且。例如坝茎,“Hello”字符串就是由’H’涤姊、’e’暇番、’l’、’l’思喊、’o’壁酬、五個字符組成,在某些程序語言中,字符串是以字符數(shù)組的方式存在舆乔,然而在Java中岳服,字符串是java.lang.String實例,用來打包字符數(shù)組希俩。所有用””包括的一串字符都是字符串吊宋。

        String name="sophie";//創(chuàng)建String對象
        System.out.println(name);//輸出sophie
        System.out.println(name.length());//顯示長度為6
        System.out.println(name.charAt(0));//顯示第1個字符s
        System.out.println(name.toUpperCase());//顯示全大寫SOPHIE

因為字符串在Java中是對象,所以它有很多的方法颜武,上面的示例給大家看到了幾個很常用的字符串方法璃搜,length()可以獲得字符串長度;charAt()可以獲得指定下標的字符鳞上,toUpperCase()可以把所有小寫字母轉成大寫字母这吻。
如果已有一個char[]數(shù)組,也可以使用new來創(chuàng)建String對象篙议。如:

        char[] ch={'H','e','l','l','o'};
        String str=new String(ch);

也可以使用toCharArray()方法唾糯,將字符串以char[]的形式返回。

char[] ch2=str.toCharArray()

Java中可以使用+運算來連接字符串鬼贱。前面我們一直在用移怯。
為了認識數(shù)組與字符串,可以看看程序入口main()方法的String[] args參數(shù)这难,在啟動JVM并指定執(zhí)行類時芋酌,可以一并指定命令行參數(shù)。

/**
 * Avarage.java
 * @author mouyong
 */
public class Avarage {
    public static void main(String[] args) {
        long sum=0;
        for(String arg:args){
            sum+=Long.parseLong(arg);//把字符串轉化為長整型
        }
        System.out.println("平均:"+(float)sum/args.length);
    }
}

在NetBeans中如果要提供命令行參數(shù)雁佳,可以這樣進行操作脐帝。

  • (1)在項目上右擊,在彈出的快捷菜單中選擇“屬性”糖权,打開“項目屬性”對話框堵腹,在左邊的“類別”列表中選擇“運行”。


圖4.15配置命令行參數(shù)

  • (2)單擊右側上方“配置”列表框旁邊的“新建…”按鈕星澳,打開“創(chuàng)建新的配置”對話框疚顷,在“類別”文本框中填入配置的名稱,我填的是“命令行參數(shù)”禁偎。


圖4.16創(chuàng)建新的配置

  • (3)單擊“主類”文本框右側的“瀏覽…”按鈕腿堤,從中選擇你寫的示例。
  • (4)在“參數(shù)”文本框中手工輸入?yún)?shù)1 2 3 4如暖,注意笆檀,每個數(shù)字之間要用空格分開,不然JVM會認為你只輸入了一個參數(shù)盒至。
    這樣設定之后酗洒,點擊工具欄上的“運行”按鈕士修,就會按你所設置的配置調用程序了。

4.4.2 字符串特性

各程序語言會有細微樱衷、重要且不容忽視的特性棋嘲。在Java的字符串來說,就有一些必須注意的特性:
? 字符串常量和字符串池矩桂。
? “不可變”(Immutable)的字符串沸移。
*1.字符串常量與字符串池
來看下面的片段:

String name1=new String("Hello");
String name2=new String("Hello");
System.out.println(name1==name2);

希望現(xiàn)在的你會很自信的回答:結果是false。是的侄榴,結果的確是false阔籽。因為name1和name2引用了不同的對象,盡管它們的內容一樣牲蜀,但內存地址不同笆制,所以==的比較結果就是false。


圖4.17片段執(zhí)行結果

再看下面的片段:

String name1="Hello";
String name2="Hello";
System.out.println(name1==name2);

這個代碼和上面似乎沒啥區(qū)別嘛涣达,只不過沒有顯式new而已在辆。但是如果你運行一下,你就會驚訝的發(fā)現(xiàn):結果是true!!!


圖4.18片段執(zhí)行結果
難道這里使用了不同的規(guī)則度苔?答案是:沒有匆篓,和前面的顯式new的規(guī)則是一致的!所以正確的推論是:name1和name2都指向了同一個對象寇窑!
在Java中為了效率的考慮鸦概,以””包括的字符串,只要內容相同(序列甩骏、大小寫相同)窗市,無論在程序中出現(xiàn)幾次,JVM都只會建立一個String對象饮笛,并在字符串池中維護咨察。在上面這個程序片段的第一行,JVM會建立一個String實例放在字符串池中福青,并把地址賦值給name1摄狱,而第二行則是讓name2直接引用了字符串池中的同一個String對象。
用””寫下的字符串稱為字符串常量(String Literal)无午,既然你用”Hello”寫死了字符串內容媒役,基于節(jié)省內存的考慮,自然就不用為這些字符串常量分別建立String實例宪迟。
前面一直強調酣衷,如果想比較對象的內容是否相同,不要使用==踩验,要使用equals()鸥诽。這個同樣適用String商玫。
2.不可變動字符串
在Java中箕憾,字符串對象一旦建立牡借,就無法更改對象中任何內容,對象沒有提供任何方法可以更改字符串內容袭异。那么+連字符串是怎么做到的呢钠龙?

String name1=”Java”;
String name2=name1+”World”;
System.out.println(name2);

上面這個程序片段會顯示JavaWorld,由于無法更改字符串對象內容御铃,所以絕不是在name1引用的字符串對象之后附加World碴里。而創(chuàng)建了java.lang.StringBuilder對象,使用其append()方法來進行+左右兩邊字符串附加上真,最后再轉換為toString()返回咬腋。
簡單地說,使用+連接字符串會產生新的String對象睡互,這并不是告訴你根竿,不要使用+連接字符串,畢竟這種做法非常方便就珠。但是不要將+用在重復性的連接場合寇壳,比如循環(huán)或遞歸時。這會因為頻繁產生新對象妻怎,造成效能上的負擔壳炎。
比如,如果我們想輸出一個從1加到100的算式(注意逼侦,不是1到100相加的結果匿辩,而是顯示描述1加到100的這個算式:1+2+3+4+5……+100),你會怎么寫榛丢?

也許是這樣寫撒汉?
for(int i=1;i<100;i++){
    System.out.print(i+"+");
}

System.out.println(100);

這樣寫代碼很簡潔,但是一個一個循環(huán)輸出效能是很低的涕滋。有沒有更好的辦法睬辐?

String str="";
for(int i=1;i<100;i++){
    str+=i+"+";
}
System.out.println(str+100);

只有一個輸出語句,效能大大提高宾肺!但是使用了連接字符串溯饵,會造成頻繁產生新對象的問題。象上面這樣的情況下锨用,強烈建議使用StringBuilder丰刊!

/**
 * OneTo100.java
 * @author mouyong
 */
public class OneTo100 {
    public static void main(String[] args) {
        StringBuilder builder=new StringBuilder();
        for(int i=1;i<100;i++){
            builder.append(i).append("+");
        }
        System.out.println(builder.append(100).toString());
    }
}

StringBuilder每次append()調用之后,都會返回原StringBuilder對象增拥,所以我們可以連接調用append()方法啄巧。這個程序只產生一個StringBuilder對象寻歧,只進行一次輸出,無論是從計算效能還是內存使用效能上來說秩仆,都是非常棒的码泛!

提示:java.lang.StringBuilder是JDK5之后新增的類,在該版本之前澄耍,我們有java.lang.StringBuffer噪珊,StringBuilder和StringBuffer其實是一樣的。但是StringBuilder的效率更高齐莲,因為他不考慮多線程情況下的同步問題痢站。所以如果你的程序會涉及到多線程的情況,可以直接改用StringBuffer

4.4.3 字符串編碼

你我都是中國人(默然說話:對的选酗!下面要談論的問題與中文有關阵难,如果你就不使用中國字,那可以略過)芒填,在Java中你必然要處理中文呜叫,所以你要了解Java如何處理中文。
要知道氢烘,java源代碼文檔在NetBeans中是UTF-8編碼怀偷。在windows簡體中文版下默認是GB2312。在Eclipse中情況又會不同播玖,Eclipse會自動讓java源代碼文件的編碼是所在操作系統(tǒng)的默認編碼椎工。所以,如果你的Eclipse在Windows簡體中文下就是GB2312蜀踏,如果是在Mac下维蒙,就會是UTF-8。
如果你使用的是GB2312編碼果覆,在編譯器編譯你的代碼時颅痊,會自動把所有的中文都轉為Unicode編碼。比如”哈啰”就會變成”\u54C8\u56C9”局待。這個”\uxxxx”就是Unicode的編碼形式斑响。
那么編譯器是如何知道要將中國字轉成哪種Unicode編碼呢?當你使用javac指令沒有指定-encodding參數(shù)時钳榨,會使用操作系統(tǒng)默認編碼舰罚,如果你的源代碼文件采用了不同的編碼形式,則必須指定-encoding參數(shù)薛耻。
提示:在Windows下不要使用純文本編輯器轉存UTF-8文件來編寫源代碼营罢,因為記事本會在文檔頭加BOM,這樣會造成Java編譯器無法編譯饼齿。建議使用NotePad++饲漾。
IDE也是允許你自定義編碼的蝙搔,如果是NetBeans,可以在項目上右擊考传,在彈出的快捷菜單中選擇“屬性”吃型,打開“項目屬性”對話框,在左邊“類別”列表中選擇“源”伙菊。然后在右側最下方的“編碼”選擇框中選擇代碼的編碼败玉。

4.5 查詢Java API文件

書上提到的各種Java類是如何知道應該調用什么方法呢敌土?是通過查詢Java API文檔知道的镜硕。
http://docs.oracle.com/javase/8/docs/api/
這個鏈接就是Java API文檔,里面包括了所有Java類的方法屬性及使用介紹返干、特點介紹兴枯。
不過在平時如果知道一個Java類,想知道怎么用矩欠,我更習慣用下面這個鏈接财剖。
http://www.baidu.com/
以前喜歡用谷歌,現(xiàn)在用不了癌淮,只好將就著用了躺坟。

4.6 重點復習

要產生對象必須先定義類,類是對象的模板乳蓄,對象是類的實例咪橙。定義類使用class關鍵字,實例化對象使用new關鍵字虚倒。
想在建立對象時美侦,一并進行某個初始流程,可以定義構造函數(shù)魂奥,構造函數(shù)是與類名同名的方法菠剩,它不能寫返回值。參數(shù)根據(jù)需要指定耻煤,也可以沒有參數(shù)具壮。
Java遵守IEEE 754浮點運算規(guī)范,使用分數(shù)與指數(shù)來表示浮點數(shù)哈蝇。如果要求精確度棺妓,那就要小心使用浮點數(shù)。不要使用==直接比較浮點數(shù)運算結果买鸽。
要讓基本類型象對象一樣的操作涧郊,可以使用Long、Integer眼五、Double妆艘、Float等類來打包基本類型彤灶。JDK5之后提供了自動裝箱和拆箱,媽媽再也不擔心我不會裝箱和拆箱了批旺。
數(shù)組在Java中就是對象幌陕,下標從0開始,下標超出范圍會拋異常汽煮。
無論是System.arraycopy()還是Arrays.copyOf()搏熄,用在類的數(shù)組時,都是執(zhí)行淺層復制暇赤。
字符串也是對象心例。
字符串對象一旦建立,無法更改對象內容鞋囊。不要將+用在重復性的連接場合止后。
使用javac指令沒有指定-encoding參數(shù)時,會使用操作系統(tǒng)默認編碼溜腐。

4.7 課后練習

4.7.1 選擇題

  1. 如果有以下的程序代碼:
int x=100;
int y=100;
Integer wx=x;
Integer wy=y;
System.out.println(x==y);
System.out.println(wx==wy);

在JDK 5以上的環(huán)境編譯與執(zhí)行译株,則顯示結果是()
A.true、true
B.true挺益、false
C.false歉糜、true
D.編譯失敗

  1. 如果有以下的程序代碼:
int x=200;
int y=200;
Integer wx=x;
Integer wy=y;
System.out.println(x==y);
System.out.println(wx==wy);
在JDK 5以上的環(huán)境編譯與執(zhí)行,則顯示結果是()
A.true望众、true 
B.true匪补、false 
C.false、true    
D.編譯失敗
  1. 如果有以下的程序代碼:
int x=300;
int y=300;
Integer wx=x;
Integer wy=y;
System.out.println(wx.equals(x));
System.out.println(wy.equals(y));

在JDK 5以上的環(huán)境編譯與執(zhí)行黍檩,則顯示結果是()
A.true叉袍、true
B.true、false
C.false刽酱、true
D.編譯失敗

  1. 如果有以下的程序代碼:
int[] arr1={1,2,3};
int[] arr2=arr1;
arr2[1]=20;
System.out.println(arr1[1]);

在JDK 5以上的環(huán)境編譯與執(zhí)行喳逛,則顯示結果是()
A.執(zhí)行時顯示2
B.執(zhí)行時顯示20
C.執(zhí)行時出現(xiàn)ArrayIndexOfBuondException
D.編譯失敗

  1. 如果有以下的程序代碼:
int[] arr1={1,2,3};
int[] arr2=new int[arr1.length]
arr2=arr1;
for(int value:arr2){
    System.out.print(value);
}

在JDK 5以上的環(huán)境編譯與執(zhí)行,則顯示結果是()
A.執(zhí)行時顯示123
B.執(zhí)行時顯示12300
C.執(zhí)行時出現(xiàn)ArrayIndexOfBuondException
D.編譯失敗

  1. 如果有以下的程序代碼:
String[] strs=new String[5]

以下描述正確的是()
A.產生5個String對象
B.產生1個String對象
C.產生0個String對象
D.編譯失敗

  1. 如果有以下的程序代碼:
    String[] strs={“java”, “java”, “java”, “java”, “java”}
    以下描述正確的是()
    A.產生5個String對象 B.產生1個String對象
    C.產生0個String對象 D.編譯失敗

  2. 如果有以下的程序代碼:

String[][] strs=new String[2][5]

以下描述正確的是()
A.產生10個String對象
B.產生2個String對象
C.產生0個String對象
D.編譯失敗

  1. 如果有以下的程序代碼:
String[][] strs={
{“java”, “java”, “java”},
{“java”, “java”, “java”, “java”}
};
System.out.println(strs.length);
System.out.println(strs[0].length);
System.out.println(strs[1].length);

以下描述正確的是()
A.顯示2棵里、3润文、4
B.顯示2、0殿怜、1
C.顯示1典蝌、2、3
D.編譯失敗

  1. 如果有以下的程序代碼:
String[][] strs={
{“java”, “java”, “java”},
{“java”, “java”, “java”, “java”}
};
for(row:strs){
for(value:row){
    …
}
}

空白處應該分別填上()
A.String头谜、String
B.String骏掀、String[]
C.String[]、String
D.String[]、String[]

4.7.2 操作題

1.Fibonacci為13 歐洲數(shù)學家截驮,在他的著作中提過笑陈,若一只兔子每月生一只小兔子,一個月后小兔子也開始生產葵袭。起初只有一只小兔子涵妥,一個月后有兩只兔子,兩個月后有三只兔子坡锡,三個月后有五只 …蓬网,也就是每個月兔子總數(shù)會是1、1鹉勒、2帆锋、3、5贸弥、8窟坐、13海渊、21绵疲、34、89臣疑,這就是費氏數(shù)列盔憨,可用公式定義如下:
fn=fn-1+fn-2 if n>1
fn=n if n=0,1
編寫程序,可以讓用戶輸入想計算的費氏數(shù)列的個數(shù)讯沈,由程序全部顯示出來郁岩。
2.請編寫一個簡單的洗 程序,可以在文本模式下顯示洗牌結果缺狠。
3.下面是一個數(shù)組问慎,請使用程序使其中元素排序為由小到大:
int[] number={70,80,31,37,10,1,48,60,33,80};
4.下面是一個排序后的數(shù)組滞伟,請編寫程序可讓用戶在數(shù)組中尋找指定數(shù)字掏愁,找到就顯示索引值曙咽,找不到就顯示-1:
int number={1,10,31,33,37,48,60,70,80};

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末揪漩,一起剝皮案震驚了整個濱河市扶镀,隨后出現(xiàn)的幾起案子饮六,更是在濱河造成了極大的恐慌仑最,老刑警劉巖朴则,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歇终,死亡現(xiàn)場離奇詭異社证,居然都是意外死亡,警方通過查閱死者的電腦和手機评凝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門追葡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事宜肉〖苍” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵崖飘,是天一觀的道長榴捡。 經常有香客問我,道長朱浴,這世上最難降的妖魔是什么吊圾? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮翰蠢,結果婚禮上项乒,老公的妹妹穿的比我還像新娘。我一直安慰自己梁沧,他們只是感情好檀何,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著廷支,像睡著了一般频鉴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上恋拍,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天垛孔,我揣著相機與錄音,去河邊找鬼施敢。 笑死周荐,一個胖子當著我的面吹牛,可吹牛的內容都是我干的僵娃。 我是一名探鬼主播概作,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼默怨!你這毒婦竟也來了讯榕?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤先壕,失蹤者是張志新(化名)和其女友劉穎瘩扼,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垃僚,經...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡集绰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谆棺。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片栽燕。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡罕袋,死狀恐怖,靈堂內的尸體忽然破棺而出碍岔,到底是詐尸還是另有隱情浴讯,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布蔼啦,位于F島的核電站榆纽,受9級特大地震影響,放射性物質發(fā)生泄漏捏肢。R本人自食惡果不足惜奈籽,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸵赫。 院中可真熱鬧衣屏,春花似錦、人聲如沸辩棒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽一睁。三九已至钻弄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卖局,已是汗流浹背斧蜕。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留砚偶,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓洒闸,卻偏偏與公主長得像染坯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子丘逸,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理单鹿,服務發(fā)現(xiàn),斷路器深纲,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • 第5章 引用類型(返回首頁) 本章內容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學一百閱讀 3,212評論 0 4
  • 醫(yī)院是最無情的地方也是最有情的地方湃鹊。在我還沒有踏上學醫(yī)之旅的時候儒喊,我一直很害怕到醫(yī)院去,因為自己小時候就...
    小爬姑娘閱讀 247評論 0 0
  • iOS逆向入門實踐 — 逆向微信币呵,偽裝定位(一) iOS 逆向開發(fā)小試-釘釘篇 粉絲福利怀愧,Pokemon Go 鎖...
    愛我你就抱抱我閱讀 142評論 0 0
  • 公司今年事情特別多,無論是外面來的,還是內部的芯义,各種風波漩渦哈垢,處在這中心,深深地感覺人生無常扛拨。 就在上個星期二耘分,我...
    黑土卡卡西閱讀 99評論 0 2