6. Java基礎(chǔ)類庫

以下是《瘋狂Java講義》中的一些知識,如有錯誤浅蚪,煩請指正挟鸠。

與用戶互動

Java程序的參數(shù)
如果運行Java程序時在類名后緊跟一個或多個字符串(多個字符串之間以空格隔開),JVM就會把這些字符串依次賦給args數(shù)組元素米辐。
如果某參數(shù)本身包含了空格,則應(yīng)該將該參數(shù)用雙引號(")括起來书释,否則JVM會把這個空格當成參數(shù)分隔符翘贮,而不是當成參數(shù)本身。

使用Scanner獲取鍵盤輸入
使用Scanner類可以很方面地獲取用戶的鍵盤輸入爆惧,Scanner是一個基于正則表達式的文本掃描器狸页,它可以從文件、輸入流检激、字符串中解析出基本類型值和字符串值肴捉。Scanner類提供了多個構(gòu)造器,不同的構(gòu)造器可接受文件叔收、輸入流、字符串作為數(shù)據(jù)源傲隶,用于從文件饺律、輸入流、字符串中解析數(shù)據(jù)跺株。
Scanner主要提供了兩個方法來掃描輸入:

  • hasNextXxx():是否還有下一個輸入項复濒,其中Xxx可以是Int脖卖、Long等代表基本數(shù)據(jù)類型的字符串。如果需要判斷是否包含下一個字符串巧颈,則可以省略Xxx畦木。
  • nextXxx():獲取下一個輸入項。Xxx的含義與前一個方法中Xxx相同砸泛。
import java.util.*;
public class ScannerKeyBoardTest
{
    public static void main(String[] args)
    {
        // System.in代表標準輸入十籍,就是鍵盤輸入
        Scanner sc = new Scanner(System.in);
        // 增加下面一行將只把回車作為分隔符
        // sc.useDelimiter("\n");
        // 判斷是否還有下一個輸入項
        while(sc.hasNext())
        {
            // 輸出輸入項
            System.out.println("鍵盤輸入的內(nèi)容是:"
                + sc.next());
        }
    }
}

獲取任意類型的輸入項

import java.util.*;
public class ScannerLongTest
{
    public static void main(String[] args)
    {
        // System.in代表標準輸入,就是鍵盤輸入
        Scanner sc = new Scanner(System.in);
        // 判斷是否還有下一個long型整數(shù)
        while(sc.hasNextLong())
        {
            // 輸出輸入項
            System.out.println("鍵盤輸入的內(nèi)容是:"
                + sc.nextLong());
        }
    }
}

文件讀取

import java.util.*;
import java.io.*;
public class ScannerFileTest
{
    public static void main(String[] args)
        throws Exception
    {
        // 將一個File對象作為Scanner的構(gòu)造器參數(shù)唇礁,Scanner讀取文件內(nèi)容
        Scanner sc = new Scanner(new File("ScannerFileTest.java"));
        System.out.println("ScannerFileTest.java文件內(nèi)容如下:");
        // 判斷是否還有下一行
        while(sc.hasNextLine())
        {
            // 輸出文件中的下一行
            System.out.println(sc.nextLine());
        }
    }
}

系統(tǒng)相關(guān)

System類
System類提供了代表標準輸入勾栗、標準輸出和錯誤輸出的類屬性;并提供了一些靜態(tài)方法用于訪問環(huán)境變量盏筐、系統(tǒng)屬性的方法围俘;還提供了加載文件和動態(tài)鏈接庫的方法。下面程序通過System類來訪問操作的環(huán)境變量和系統(tǒng)屬性琢融。

import java.io.*;
import java.util.*;
public class SystemTest
{
    public static void main(String[] args) throws Exception
    {
        // 獲取系統(tǒng)所有的環(huán)境變量
        Map<String,String> env = System.getenv();
        for (String name : env.keySet())
        {
            System.out.println(name + " ---> " + env.get(name));
        }
        // 獲取指定環(huán)境變量的值
        System.out.println(System.getenv("JAVA_HOME"));
        // 獲取所有的系統(tǒng)屬性
        Properties props = System.getProperties();
        // 將所有系統(tǒng)屬性保存到props.txt文件中
        props.store(new FileOutputStream("props.txt")
            , "System Properties");
        // 輸出特定的系統(tǒng)屬性
        System.out.println(System.getProperty("os.name"));
    }
}

如果兩個對象的相同界牡,一定是同一個對象。


public class IdentityHashCodeTest
{
    public static void main(String[] args)
    {
        // 下面程序中s1和s2是兩個不同對象
        String s1 = new String("Hello");
        String s2 = new String("Hello");
        // String重寫了hashCode()方法——改為根據(jù)字符序列計算hashCode值漾抬,
        // 因為s1和s2的字符序列相同宿亡,所以它們的hashCode方法返回值相同
        System.out.println(s1.hashCode()
            + "----" + s2.hashCode());
        // s1和s2是不同的字符串對象,所以它們的identityHashCode值不同
        System.out.println(System.identityHashCode(s1)
            + "----" + System.identityHashCode(s2));
        String s3 = "Java";
        String s4 = "Java";
        // s3和s4是相同的字符串對象奋蔚,所以它們的identityHashCode值相同
        System.out.println(System.identityHashCode(s3)
            + "----" + System.identityHashCode(s4));
    }
}

Runtime類

Runtime類代表Java程序的運行時環(huán)境她混,每個Java程序都有一個與之對應(yīng)的Runtime實例,應(yīng)用程序通過該對象與其運行時環(huán)境相連泊碑。
應(yīng)用程序不能創(chuàng)建自己的Runtime實例坤按,但可以通過getRuntime()方法獲取與之關(guān)聯(lián)的Runtime對象。
Runtime類代表Java程序的運行時環(huán)境馒过,可以訪問JVM的相關(guān)信息臭脓,如處理器數(shù)量,內(nèi)存信息等腹忽。

public class RuntimeTest
{
    public static void main(String[] args)
    {
        // 獲取Java程序關(guān)聯(lián)的運行時對象
        Runtime rt = Runtime.getRuntime();
        System.out.println("處理器數(shù)量:"
            + rt.availableProcessors());
        System.out.println("空閑內(nèi)存數(shù):"
            + rt.freeMemory());
        System.out.println("總內(nèi)存數(shù):"
            + rt.totalMemory());
        System.out.println("可用最大內(nèi)存數(shù):"
            + rt.maxMemory());
    }
}

除此之外来累,Runtime還有一個功能:它可以直接單獨啟動一條進程來運行操作系統(tǒng)的命令。

public class ExecTest
{
    public static void main(String[] args)
        throws Exception
    {
        Runtime rt = Runtime.getRuntime();
        // 運行記事本程序
        rt.exec("notepad.exe");
    }
}

常用類

Object類
Object類是所有類窘奏、數(shù)組嘹锁、枚舉類的父類,也就是說着裹,Java允許把所有任何類型的對象賦給Object類型的變量领猾。當定義一個類時沒有使用extends關(guān)鍵字為它顯式指定父類,則該類默認繼承Object父類。

Object還提供了一個protected修飾的clone()方法摔竿,程序員可重寫該方法來實現(xiàn)“淺克隆”面粮。
自定義類實現(xiàn)“淺克隆”的步驟:

  1. 自定義類實現(xiàn)Cloneable接口。
  2. 自定義類實現(xiàn)clone()方法继低。
  3. 在clone()方法中通過super.clone()調(diào)用Object的clone()方法來實現(xiàn)“淺克隆”熬苍。
class Address
{
    String detail;
    public Address(String detail)
    {
        this.detail = detail;
    }
}
// 實現(xiàn)Cloneable接口
class User implements Cloneable
{
    int age;
    Address address;
    public User(int age)
    {
        this.age = age;
        address = new Address("廣州天河");
    }
    // 通過調(diào)用super.clone()來實現(xiàn)clone()方法
    public User clone()
        throws CloneNotSupportedException
    {
        return (User)super.clone();
    }
}
public class CloneTest
{
    public static void main(String[] args)
        throws CloneNotSupportedException
    {
        User u1 = new User(29);
        // clone得到u1對象的副本。
        User u2 = u1.clone();
        // 判斷u1袁翁、u2是否相同
        System.out.println(u1 == u2);      //false
        // 判斷u1柴底、u2的address是否相同
        //不會對引用類型的成員變量值所引用的對象進行深克隆
        System.out.println(u1.address == u2.address);     //true
    }
}

復(fù)制出來的只是原有對象的副本,只是一種淺克隆梦裂,只克隆該對象的所有成員變量值似枕,不會對引用類型的成員變量值所引用的對象進行深克隆。深克隆需要開發(fā)者子集進行遞歸克隆年柠。

Objects類
題外話:工具類命名習慣是添加s凿歼,如Arrays、Collections冗恨。
hashCode():返回指定對象的hashCode值答憔。
toString:返回指定對象的“描述性”字符串。
requiredNonNull:檢查對象是否為null掀抹。主要用于對方法形參進行輸入校驗虐拓。

import java.util.Objects;
public class ObjectsTest
{
    // 定義一個obj變量,它的默認值是null
    static ObjectsTest obj;
    public static void main(String[] args)
    {
        // 輸出一個null對象的hashCode值傲武,輸出0
        System.out.println(Objects.hashCode(obj));
        // 輸出一個null對象的toString蓉驹,輸出null
        System.out.println(Objects.toString(obj));
        // 要求obj不能為null,如果obj為null則引發(fā)異常
        System.out.println(Objects.requireNonNull(obj
            , "obj參數(shù)不能是null揪利!"));
    }
}

String态兴、StringBuffer和StringBuilder

字符串就是一連串的字符序列,Java提供了String和StringBuffer兩個類來封裝對字符串疟位,并提供了系列方法來操作字符串對象瞻润。
String類是不可變類的,
StringBuffer對象則代表一個字符序列可變的字符串甜刻,當一個StringBuffer被創(chuàng)建以后绍撞,通過StringBuffer提供的append、insert得院、reverse傻铣、setCharAt、setLength等方法可以改變這個字符串對象的字符序列祥绞。一旦通過StringBuffer生成了最終想要的字符串矾柜,就可以調(diào)用它的toString方法將其轉(zhuǎn)換為一個String對象阱驾。
JDK1.5又新增了一個StringBuilder類就谜,它也代表了字符串對象怪蔑。StringBuilder是線程不安全的。

public class StringBuilderTest
{
    public static void main(String[] args)
    {
        StringBuilder sb = new StringBuilder();
        // 追加字符串
        sb.append("java");//sb = "java"
        // 插入
        sb.insert(0 , "hello "); // sb="hello java"
        // 替換
        sb.replace(5, 6, ","); // sb="hello, java"
        // 刪除
        sb.delete(5, 6); // sb="hellojava"
        System.out.println(sb);
        // 反轉(zhuǎn)
        sb.reverse(); // sb="avajolleh"
        System.out.println(sb);
        System.out.println(sb.length()); // 輸出9
        System.out.println(sb.capacity()); // 輸出16
        // 改變StringBuilder的長度丧荐,將只保留前面部分
        sb.setLength(5); // sb="avajo"
        System.out.println(sb);
    }
}

Math 類
Math類是一個工具類缆瓣,它的構(gòu)造器被定義成private的,因此無法創(chuàng)建Math類的對象虹统;Math類中所有方法都是類方法弓坞,可以直接通過類名來調(diào)用它們。

Random與ThreadLocalRandom
Random類專門用于生成一個偽隨機數(shù)车荔,它有兩個構(gòu)造器:一個構(gòu)造器使用默認的種子渡冻,另一個構(gòu)造器需要程序員顯式傳入一個long型整數(shù)的種子。
相對于Math的random()方法而言忧便,Random類的提供了更多方法來生成各種偽隨機數(shù)族吻,它不僅可以生成浮點類型的偽隨機數(shù),也可以生成整數(shù)類型的偽隨機數(shù)珠增,還可以指定生成隨機數(shù)的范圍超歌。
ThreadLocalRandom是Java7新增的,它可以在多線程環(huán)境下代替Random減少多線程資源競爭蒂教,從而提供更好的線程安全巍举。

import java.util.*;
public class RandomTest
{
    public static void main(String[] args)
    {
        Random rand = new Random();
        System.out.println("rand.nextBoolean():"
            + rand.nextBoolean());
        byte[] buffer = new byte[16];
        rand.nextBytes(buffer);
        System.out.println(Arrays.toString(buffer));
        // 生成0.0~1.0之間的偽隨機double數(shù)
        System.out.println("rand.nextDouble():"
            + rand.nextDouble());
        // 生成0.0~1.0之間的偽隨機float數(shù)
        System.out.println("rand.nextFloat():"
            + rand.nextFloat());
        // 生成平均值是 0.0,標準差是 1.0的偽高斯數(shù)
        System.out.println("rand.nextGaussian():"
            + rand.nextGaussian());
        // 生成一個處于int整數(shù)取值范圍的偽隨機整數(shù)
        System.out.println("rand.nextInt():" + rand.nextInt());
        // 生成0~26之間的偽隨機整數(shù)
        System.out.println("rand.nextInt(26):" + rand.nextInt(26));
        // 生成一個處于long整數(shù)取值范圍的偽隨機整數(shù)
        System.out.println("rand.nextLong():" +  rand.nextLong());
    }
}

BigDecimal
float凝垛、double兩種基本浮點類型的浮點數(shù)容易引起精度丟失懊悯。
程序中需要對double浮點數(shù)進行加、減梦皮、乘炭分、除基本運算赴肚,則需要先將double類型數(shù)值包裝成BigDecimal對象隧饼,調(diào)用BigDecimal對象的方法執(zhí)行運算后再將結(jié)果轉(zhuǎn)換成double型變量。

public class BigDecimalTest
{
    public static void main(String[] args)
    {
        BigDecimal f1 = new BigDecimal("0.05");
        BigDecimal f2 = BigDecimal.valueOf(0.01);
        BigDecimal f3 = new BigDecimal(0.05);
        System.out.println("使用String作為BigDecimal構(gòu)造器參數(shù):");
        System.out.println("0.05 + 0.01 = " + f1.add(f2));
        System.out.println("0.05 - 0.01 = " + f1.subtract(f2));
        System.out.println("0.05 * 0.01 = " + f1.multiply(f2));
        System.out.println("0.05 / 0.01 = " + f1.divide(f2));
        System.out.println("使用double作為BigDecimal構(gòu)造器參數(shù):");
        System.out.println("0.05 + 0.01 = " + f3.add(f2));
        System.out.println("0.05 - 0.01 = " + f3.subtract(f2));
        System.out.println("0.05 * 0.01 = " + f3.multiply(f2));
        System.out.println("0.05 / 0.01 = " + f3.divide(f2));
    }
}

注意:創(chuàng)建BigDecimal對象時铸屉,不要直接使用double浮點數(shù)作為構(gòu)造器參數(shù)調(diào)用BigDecimal構(gòu)造器
退子。否則會有精度損失岖妄。

日期時間類

Date類
Date類從JDK1.0起就開始存在了。但正因為它歷史悠久寂祥,所以它的大部分構(gòu)造器荐虐、方法都已經(jīng)過時,不再推薦使用了

Calender類
因為Date類的設(shè)計上存在一些缺陷丸凭,Java提供了Calendar類來更好地處理日期和時間福扬。Calendar是一個抽象類腕铸,它用于表示日歷。
Calendar本身是一個抽象類铛碑,它是所有日歷類的模板狠裹,并提供了一些所有日歷通用的方法,但它本身不能直接實例化汽烦。程序只能創(chuàng)建Calendar子類的實例涛菠,Java本身提供了一個GregorianCalendar類,一個代表Gregorian Calendar的子類撇吞,它代表了我們通常所說的公歷俗冻。
開發(fā)者可以開發(fā)自己的Calendar子類。

import java.util.*;
public class CalendarTest
{
    public static void main(String[] args)
    {
        Calendar c = Calendar.getInstance();
        // 取出年
        System.out.println(c.get(YEAR));
        // 取出月份
        System.out.println(c.get(MONTH));
        // 取出日
        System.out.println(c.get(DATE));
        // 分別設(shè)置年牍颈、月迄薄、日、小時煮岁、分鐘讥蔽、秒
        c.set(2003 , 10 , 23 , 12, 32, 23); //2003-11-23 12:32:23
        System.out.println(c.getTime());
        // 將Calendar的年前推1年
        c.add(YEAR , -1); //2002-11-23 12:32:23
        System.out.println(c.getTime());
        // 將Calendar的月前推8個月
        c.roll(MONTH , -8); //2002-03-23 12:32:23
        System.out.println(c.getTime());


        Calendar cal1 = Calendar.getInstance();
        cal1.set(2003, 7, 23, 0, 0 , 0); // 2003-8-23
        cal1.add(MONTH, 6); //2003-8-23 => 2004-2-23
        System.out.println(cal1.getTime());


        Calendar cal2 = Calendar.getInstance();
        cal2.set(2003, 7, 31, 0, 0 , 0); // 2003-8-31
        // 因為進位到后月份改為2月,2月沒有31日人乓,自動變成29日
        cal2.add(MONTH, 6); // 2003-8-31 => 2004-2-29
        System.out.println(cal2.getTime());


        Calendar cal3 = Calendar.getInstance();
        cal3.set(2003, 7, 23, 0, 0 , 0); //2003-8-23
        // MONTH字段“進位”勤篮,但YEAR字段并不增加
        cal3.roll(MONTH, 6); //2003-8-23 => 2003-2-23
        System.out.println(cal3.getTime());


        Calendar cal4 = Calendar.getInstance();
        cal4.set(2003, 7, 31, 0, 0 , 0); //2003-8-31
        // MONTH字段“進位”后變成2,2月沒有31日色罚,
        // YEAR字段不會改變碰缔,2003年2月只有28天
        cal4.roll(MONTH, 6); //2003-8-31 => 2003-2-28
        System.out.println(cal4.getTime());
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市戳护,隨后出現(xiàn)的幾起案子金抡,更是在濱河造成了極大的恐慌,老刑警劉巖腌且,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梗肝,死亡現(xiàn)場離奇詭異,居然都是意外死亡铺董,警方通過查閱死者的電腦和手機巫击,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來精续,“玉大人坝锰,你說我怎么就攤上這事≈馗叮” “怎么了顷级?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長确垫。 經(jīng)常有香客問我弓颈,道長帽芽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任翔冀,我火速辦了婚禮导街,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘橘蜜。我一直安慰自己菊匿,他們只是感情好,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布计福。 她就那樣靜靜地躺著,像睡著了一般徽职。 火紅的嫁衣襯著肌膚如雪象颖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天姆钉,我揣著相機與錄音说订,去河邊找鬼。 笑死潮瓶,一個胖子當著我的面吹牛陶冷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播毯辅,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼埂伦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了思恐?” 一聲冷哼從身側(cè)響起沾谜,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎胀莹,沒想到半個月后基跑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡描焰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年媳否,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荆秦。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡篱竭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出萄凤,到底是詐尸還是另有隱情室抽,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布靡努,位于F島的核電站坪圾,受9級特大地震影響晓折,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜兽泄,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一漓概、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧病梢,春花似錦胃珍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至钮热,卻和暖如春填抬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背隧期。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工飒责, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人仆潮。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓宏蛉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親性置。 傳聞我的和親對象是個殘疾皇子拾并,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容