1. 程式人生 > >201711671203《Java程式設計》第十二週(1)(合集版)

201711671203《Java程式設計》第十二週(1)(合集版)

這周的學習報告分兩份,第一份是將過往偷懶的,沒整理全的知識點進行補充,順帶複習,第二份則針對Java網路程式設計、繪圖以及泛型與集合框架這三個大的點進行整理(可能寫不完拖到第十三週吧(#^.^#))

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

一、Java入門 

(一)每種語言之所以至今仍然被使用,其原因是因為它不可以被完全替代,或者說它的優勢足以讓它繼續被使用。而Java最大的優勢應當是它的可移植性,同時它是一種多執行緒、穩定、面向物件的語言。順帶一提,C語言和C++沒有被替代的原因是因為他們的執行速度非常快,是最能提高硬體執行效率的語言,非常適合底層開發。

(二)Java程式開發步驟

      1、編寫原始檔    2、編譯(得到位元組碼檔案)(位元組碼檔案可以被反編譯得到原始檔)      3、執行(用Java直譯器解釋位元組碼檔案)

(三)程式編寫風格

      1、Allmans風格(獨行風格)左右大括號各佔一行

      2、Kernighan風格(行尾風格)左括號在上一行行尾,右大括號獨佔一行

註釋不提

 

二、基本資料型別及陣列(寫過的部分不再重新提起)

(一)識別符號

       用來標識類名、變數名、方法名、型別名、陣列名及檔名的有效字元序列,識別符號由字母、下劃線、美元符號和數字組成,長度不限。識別符號首字母不為數字,不能是其餘關鍵字,也不能為true、false和null。

(二)Unicode字符集

      Java使用Unicode標準字符集,其前128個字元為ascll碼。因此Java所使用的字母不僅包括通常的拉丁字母,也包括漢字、日文片假名、朝鮮文、俄文等等。

三、運算子、表示式和語句

(一)算術運算子

       加減運算子優先順序是4級,乘除和求餘運算子優先順序是3級,他們都是二目運算子,操作元都是整型或浮點型資料,結合方向都是從左到右。順便一提,自增自減運算子的操作元也只能是整型或者浮點型變數。

(二)邏輯運算子

      &&、||表示邏輯與、邏輯或,是二目運算子;!表示邏輯非,是單目運算子。邏輯運算子操作元必須是boolean型資料,但是可以連線關係表示式。

(三)位運算子

(1)按位與運算子 & 是二目運算子,對兩個整型資料a、b按位進行運算,先將資料化為32位二進位制資料,若兩個資料對應位都是1,則和的對應位為1,否則是0,如果b的精度高於a,則結果和精度與b相同。

(2)按位或運算子 | 是二目運算子,前面過程一致,若兩個資料對應位都是0,則和的對應位是0,否則為1。

(3)按位非運算子 ~ 是單目運算子,前面過程一致,若a對應位是0,則結果對應位是1,否則是0。

(4)按位異或運算 ^ 是二目運算子,前面過程一致,若兩個資料對應位相同,則結果對應位是0,否則是1

所以有a^a=0,a^0=a.  a^b^b=a

位運算子也可以操作邏輯型資料,當a、b都是true,a&b是true,否則a&b為false;當a、b都是false,a|b是false,否則a&b為true;~就不提了,類似於!。

(四)語句概述(這部分不提,C語音與C++的學習已經瞭解)

 

四、類與物件

(1) 引數傳值

在Java中,方法的所有引數都是“傳值”的

class Computer{  
    int add(int x,int y){
       return x+y;
    }
}
public class Example4_6 {
    public static void main(String args[]){
       Computer com = new Computer();
       int m = 100;
       int n = 200;
       int result = com.add(m,n);        //將m、n的值“傳值”給引數x、y
       System.out.println(result); 
       result = com.add(120+m,n*10+8);    //將表示式120+m,n*10+8的值“傳值”給引數x、y
       System.out.println(result); 
    }
}


(2)對於引用

一個類宣告的兩個物件如果具有相同的引用,兩者就具有完全相同的變數

此處提及一下餓漢式單例模式

//物件是方法被呼叫時,才初始化,也叫做物件的延時載入。成為:懶漢式。
//Single類進記憶體,物件還沒有存在,只有呼叫了getInstance方法時,才建立物件。
 class Single
 {
     private static Single s = null;//建立物件
     private Single(){}//防止被其他類對該類進行例項化,避免被呼叫
     public static Single getInstance()
     {
         //A B
         if(s==null)//如果A,B為空則進入
        {
        synchronized(Single.class)//A 進入後 此處功能是防止B進入,加入同步鎖 只允許一個例項進入
            {                
            if(s==null)//A為null
                //對A進行例項化 再返回同步快12行,此時只有一個物件B,可以進入同步鎖,到14行此時物件不為空因為例項化了A ,直接返回S
                     s = new Single();
            }
         }       
  return s;
}

 

五、子類與繼承(之前第六週學習報告寫的非常完善,這裡跳過)

六、介面與實現(跳過)

七、內部類與異常類(當時因為不理解就暫時略過了,此處整理就從頭開始吧)

(1)類可以有兩種重要成員:成員變數和方法,而Java還允許類可以有一種成員:內部類。   Java支援在一個類中定義另一個類,這樣的類稱內部類,包含內部類的類成為內部類的外嵌類

內部類和外嵌類之間的重要關係有    1、內部類的外嵌類的成員變數在內部類有效,內部類的方法可以呼叫外嵌類的方法   2、內部類的類體不可以宣告類變數和類方法,外嵌類的類體可以用內部類宣告物件作為外嵌類的成員   3、內部類僅供它的外嵌類使用

舉例

public class RedCowForm {
   static String formName;
   RedCow cow;  //內部類宣告物件
   RedCowForm() {
   }
   RedCowForm(String s) {
      cow = new RedCow(150,112,5000);
      formName = s;
   }
   public void showCowMess() {
      cow.speak();
   }
   class RedCow {  //內部類的宣告
      String cowName = "紅牛";
      int height,weight,price;
      RedCow(int h,int w,int p){
          height = h;
          weight = w;
          price = p;
      }
      void speak() {
         System.out.println("偶是"+cowName+",身高:"+height+"cm 體重:"+weight+"kg,生活在"+formName);
      }
   }    //內部類結束
} 

(2)關於匿名類作用不理解......跳過

(3)異常類

1、所謂異常就是程式執行時可能出現的一些錯誤,異常處理將會改變程式的控制流程,讓程式有機會對錯誤做出處理。

Java使用throw關鍵字丟擲一個Exception子類的例項表示異常發生,允許方法呼叫過程中丟擲異常物件,終止當前方法的繼續執行。

2、Java使用try-catch處理異常,將可能出現的異常操作放在try部分,一但try丟擲異常物件,那麼try部分立刻結束執行,轉向執行相應的catch部分。

3、編寫程式時,可以擴充套件Exception類定義自己的異常類。throw是關鍵字,與throws是不同的關鍵字

4、斷言

斷言語句一般用於程式不準備通過捕獲異常來處理的錯誤,要求程式必須立即停止執行。在除錯程式碼階段,可以讓斷言語句發揮作用,正式執行是可以關閉斷言語句但仍把斷言語句保留在原始碼中,以後可以重新啟用斷言語句。     

用Java直譯器直接執行時預設關閉斷言語句,可以使用-ea啟用斷言,如Java -ea mainClass

 

八、常用實用類

(1)String類

   String類在Java.lang包中,因為Java.lang包被預設引入,因此可以直接使用String類,因為String類是final類,因此使用者不能擴充套件,即String類沒有子類。

String常量也是物件,有String s = new String("hello world");但凡是new運算子構造出的物件都不在常量池中。

(2)字串的並置   String物件可以用“+”進行並置運算,首尾相接得到一個新的String物件。

(3)String類的常用方法

  1、String物件呼叫equals(String s)方法比較當前String物件的字元序列是否與引數s指定的String物件的字元序列相同,如

String a = new String("nihao");
String b = new String("nihao");
String c = new String("hello world");

那麼a.equals(b)的值是true,a.equals(c)是false。

2、String物件呼叫startsWith(String s)方法,判斷當前String物件的字元序列字首是否與參與引數指定的String物件的字元序列,如

String a = "你好" ,b = "不好"

那麼a.startsWith("你")的值就是true,b.startsWith("你")的值就是false.

3、那麼endsWith(String s)就是判斷後綴是否是引數s的字元序列。

4、compareTo(String s)按字典序與引數指定的String物件s的字元序列比較大小

5、contains(String s)比較當前String物件的字元序列是否包含引數s的字元序列,如,a="nihao",那麼a.contains("bu")的值就是false

6、idnexOf(String s)和lastIndexOf(String s) 對於String a = "ABC",索引位置0、1、2上的字元分別是A、B、C。                      idnexOf(String s)從當前String物件的字元序列的0索引位置開始檢索首次出現s的字元序列的位置,並返回該位置;lastIndexOf(String s)從當前String物件的字元序列的0索引位置開始檢索最後一次出現s的字元序列的位置。idnexOf(String s,int startpoint)方法是一個過載方法,引數startpoint的值用來指定檢索開始的位置。

7、substring(int startpoint)獲得一個新的String物件,新的String物件字元序列賦值當前String物件的字元序列中的startpoint位置到最後位置上的字元所得到的字元序列。呼叫substring(int start,int end)得到的新的String物件的字元序列賦值當前String物件的字元序列中的start位置至end-1位置上的字元。

(4)字串可以與基本資料相互轉化

使用public static int parseInt(String s)可以將“數字”字元組成的字元序列轉化成int型資料,同樣的也有public static int parseByte(String s),public static int parseLong(String s),public static int parseFloat(String s)等等

也可以用如public static String valueOf(int n),public static String valueOf(byte n),public static String valueOf(float n)等方法將如123、1232.98等數值轉化為String物件。

(5)正則表示式(元字元不一一列舉,詳情看書或者仔細上網查閱資料)

在正則表示式中可以用限定修飾符,如對於限定修飾符?,如果X表達正則表示式中的一個元字元或普通字元,那麼X?表示X出現了0次或1次。     如String a = "nihao[2468]?";那麼“nihao2”   “nihao4”....都是與正則表示式a匹配的字串。  又例如a = "@\\w{4}",那麼“@abcd” ,“Java” ,“世界和平”都是與正則表示式a匹配的字串。

(6)StringTokenizer類和Scanner類都可以用於分解String物件的字元序列,StringTokenizer(String s)為s構造一個分析器,使用預設的分隔標記。StringTokenizer(String s,String delim)為s構造一個分析器,引數delim的字元序列中的字元任意排列被作為分隔標記。

(7)StringBuffer類

(8)日期  format方法   format(格式化模式,日期列表)

(9)Math類,BigInteger類和Random類

Random類用於獲得隨機數,如Random random = new Random();    random.nextInt(100)可以返回一個0~99之間的某個整數

(10)

1、format方法也可以用於對數字格式化。如String s = String.format("%.2f",3.1415926535),那麼s的字元序列就是3.14            String s = String.format("%d元%0.3f公斤%d臺",888,999.777666,123); s就是“888元999.778公斤123臺”

2、%d:將值格式化為十進位制整數,%o:將值格式化為八進位制整數,%x將值格式化為小寫的十六進位制整數,%X:將值格式化為大寫的十六進位制整數。

(11)Class類 幫助程式建立其他類的例項。

(12)console類,可以用於在鍵盤輸入一行文字,又不在命令列顯示,可以用System類呼叫console()方法返回console()方法返回Console類的一個物件,如 Console cons = System.console();然後用cons呼叫readPassword()方法讀取使用者在鍵盤輸入一行文字,並將文字以一個char陣列返回: char []passwd = cons.readPassword();

 

九、元件及事件處理(跳過)

十、輸入、輸出流

程式在執行期間,可能需要從外部的儲存媒介或其他程式讀入所需要的資料,這就需要使用輸入流,程式通過輸入流讀取源中的資料,使用read()方法讀入。同樣的,也有必要使用輸出流,用write()方法把資料寫入目的地。  多有輸入流都是抽象類InputStream(位元組輸入流)或抽象類Reader(字元輸入流)的子類,而所有輸出流都是抽象類OutputStream或者Writer的子類

(1)File類 

file類物件主要用來獲取檔案本身的一些資訊如檔案所在目錄、檔案長度或者讀寫許可權,不涉及對檔案的讀寫。構造方法有三個 File(String filename);File(String directoryPath,String filename);File(File dir,String filename)directoryPath指檔案路徑dir是目錄,使用File(String filename),該檔案被認為與當前應用程式在同一目錄中。

使用file類的方法獲取檔案本身資訊 getName(); canRead()能否讀取; canWrite()能否寫入; exists()是否存在; length()獲取檔案長度,單位是位元組; getAbsolutePath()獲取檔案絕對路徑; getParent()獲取檔案父目錄;等等

(2)檔案位元組輸入流

使用輸入流有四個步驟  1、設定輸入流的源 2、建立指向源的輸入流 3、讓輸入流讀取源中的資料 4、關閉輸入流。

構造方法

FileInputStream(String name);
FileInputStream(File file);

第一個構造方法使用給定的檔名建立輸入流,第二個使用File物件建立書瑞路,引數name和file指定的檔案稱為輸入流的源。

建立輸入流,可能會出現錯誤(或者稱為異常),如檔案不存在。當出現I/O錯誤,Java生成一個出錯訊號,它使用IOException(IO異常)物件表示這個出錯訊號。程式必須在try-catch語句中try塊建立輸入流,在catch塊檢測並處理這個異常

位元組輸入流的read方法以位元組為單位讀取源中資料         輸入流提供了關閉方法close()。例子如下

import java.io.*;
public class Example10_4 {
   public static void main(String args[]) {
      int n=-1;
      byte [] a=new byte[100];
      try{  File f=new File("Example10_4.java");
            InputStream in = new FileInputStream(f);
            while((n=in.read(a,0,100))!=-1) {
               String s=new String (a,0,n);
               System.out.print(s);
            }
            in.close();
      }
      catch(IOException e) {
           System.out.println("File read Error"+e);
      }
   }
}


(3)檔案位元組輸出流類似輸入流,不再贅述。

(4)檔案字元輸入、輸出流

與FileInputStream、FileOutputStream位元組流對應的是FileReader、FileWriter字元流,不贅述

(5)緩衝流

BufferedReader和BufferedWriter類建立的物件稱為緩衝輸入、輸出流,這加強讀寫檔案的能力。例如student.txt是一個學生名單,每個姓名佔一行,如果我們要讀取名字,那麼每次必須讀取一行,使用FileReader流很難完成這樣的任務,因為我們不清楚一行有多少字元,因此Java提供更高階的流BufferedReader和BufferedWriter,二者的源和目的地必須是字元輸入、輸出流。         BufferedReader和BufferedWriter的構造方法

BufferedReader(Reader in);
BufferedWriter(Writer out);

 BufferedReader流通過方法readLine()讀取文字行,具體操作如下

FileReader one = new FileReader("a.txt");
BufferedReader two = BufferedReader(one);
String Line =  two.readLine();

這樣就讀取了a.txt檔案,類似的將FileWriter、BufferedWriter連線起來,然後使用BufferedWriter將資料寫到目的地。

(6)隨機流

RandomAccessFile類建立的流稱作隨機流,它既可以作為流的指向,也可以作為流的源,即既可以從這個流中讀取檔案中的資料,也可以通過這個流寫入資料到檔案。構造方法如下

RandomAccessFile(String name,String mode)                                                                                                                                  RandomAccessFile(File file,String mode)

file是一個File物件,給出建立的流的源,也是流目的地,name用於確定檔名,給出建立的流的源,也是流目的地。mode取r(只讀)或rw(可讀寫)許可權

(7)陣列流

流的源和目的地除了可以是檔案,也可以是計算機記憶體

因此有位元組陣列流和字元陣列流,給出例子,不細說

import java.io.*;
public class Example10_10 {
   public static void main(String args[]) {
      try {
         ByteArrayOutputStream outByte=new ByteArrayOutputStream();
         byte [] byteContent="mid-autumn festival".getBytes(); 
         outByte.write(byteContent); 
         ByteArrayInputStream inByte=new ByteArrayInputStream(outByte.toByteArray());
         byte backByte []=new byte[outByte.toByteArray().length];
         inByte.read(backByte);
         System.out.println(new String(backByte));
         CharArrayWriter outChar=new CharArrayWriter();
         char [] charContent="中秋快樂".toCharArray(); 
         outChar.write(charContent); 
         CharArrayReader inChar=new CharArrayReader(outChar.toCharArray());
         char backChar []=new char[outChar.toCharArray().length];
         inChar.read(backChar);
         System.out.println(new String(backChar));
      }
      catch(IOException exp){}
  }
}

(8)資料流

DataInputStream和DataOutputStream類建立的物件稱為資料輸入、輸出流,他們允許程式按著機器無關的風格讀取Java原始資料,即讀取一個數值時不再關心這個數值是多少位元組。構造方法如下

DataInputStream(InputStream in)建立的資料輸入流流向有引數in指定的底層輸入流,同樣的有

DataOutputStream(OutputStream out)建立的資料輸出流流向有引數out指定的底層輸出流,這兩個類的方法不一一贅述。

(9)物件流

ObjectInputStream和ObjectOutputStream類分別是InputStream和OutputStream類的子類,建立的物件稱為物件輸入、輸出流。物件輸出流使用writeObject(Object obj)方法將一個物件obj寫入一個檔案,同樣的有readObject(Object obj)讀取一個物件到程式中,構造方法如下

ObjectInputStream(InputStream in)和ObjectOutputStream(OutputStream out)

使用物件流寫入或者讀入物件時,要保證物件是序列化,這是為了保證能把物件寫入到檔案並能再把物件正確讀回到程式中。  一個類如果實現了Serializable介面(java.io包中的介面)那麼這個類建立的物件就是所謂的序列化物件

(10)序列化與物件克隆

已知一個類的兩個物件如果具有相同的引用,那麼他們具有相同的實體和功能,所以如果我們想得到物件的一個複製,而複製的變化不會引起物件實體發生變化,這樣的複製稱為原物件的一個克隆物件

我們可以將要克隆的物件寫入物件輸出流指向的目的地,然後將該目的地作為一個物件輸入流的源,那麼該物件輸入流從源中讀回的物件一定是原物件的一個克隆。即 物件輸入流通過物件的序列化資訊來得到當前物件的一個克隆。

(11)使用Scanner解析檔案

與前面第八章使用Scanner解析字串中資料類似,不贅述。

(12)帶進度條的輸入流

可以使用javax.swing包提供的輸入流類ProgressMonitorInputStream.構造方法是                                                                              ProgressMonitorInputStream(compunent c,String s,InputStream)

進度條在引數c指定的元件正前方顯示,若c=null,則在螢幕正前方顯示。

(13)檔案鎖

經常會出現幾個程式處理同一個檔案的情景,比如同時更新或讀取檔案,這樣可能發生混亂,檔案鎖可以幫助解決這樣的問題。比如RandomAccessFile建立的流在讀寫檔案是可以使用檔案鎖,只要不解除該鎖,其他程式無法操作被鎖定檔案。具體如何實現給出例子

import java.io.*;
public class Example10_19 {
   public static void main(String args[]) {
      File file=new File("Example12_15.java");
      WindowFileLock win=new WindowFileLock(file);
      win.setTitle("使用檔案鎖");
   }
}

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class WindowFileLock extends JFrame implements ActionListener {
   JTextArea text;
   JButton button;
   File file;
   RandomAccessFile input;
   FileChannel channel;
   FileLock lock;
   WindowFileLock(File f) {
      file=f;
      try {
         input=new RandomAccessFile(file,"rw"); 
         channel=input.getChannel();
         lock=channel.tryLock();
      }
      catch(Exception exp){}
      text=new JTextArea();
      button=new JButton("讀取一行");
      button.addActionListener(this);
      add(new JScrollPane(text),BorderLayout.CENTER);
      add(button,BorderLayout.SOUTH);
      setSize(300,400);
      setVisible(true);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }
   public void actionPerformed(ActionEvent e) {
      try{  
           lock.release();
           String lineString=input.readLine();
           text.append("\n"+lineString);
           lock=channel.tryLock();
           if(lineString==null)
             input.close();
      }
      catch(Exception ee){}
  }
}

從前整理到此為止。

 

參考資料 Java2實用教程(第五版)耿祥義 張躍平編著