發表文章

Java:建立有泛型的Collection陣列

最近遇到的問題,想將JMenuItem分成三類,每個類別要能動態增減,不過減得機率很少,所以建立了ArrayList帶有泛型的Collection陣列,不過卻不能直接的建立,該如何解決!? 關鍵詞: create array of java generic collection import java.util.ArrayList; import javax.swing.JMenuItem; /** 建立如何建立包函泛型的Collection陣列。 */ class ArrayOfGenericCollection { public static void main(String [] args) { // 最直覺的寫法,不過這個寫法是無法通過編譯的。 //ArrayList<JMenuItem> gat[] = new ArrayList<JMenuItem>[10]; // 下面的寫法是利用Java陣列的基本概念,加上轉型, // 不過因為動態轉型所以編譯帶有警告。 // 且執行時期因為Object無法轉成ArrayList,所以這樣也行不通。 //ArrayList<JMenuItem> gat2[] = (ArrayList<JMenuItem>[])new Object[10]; // 上面的寫法,既然無法將Object轉成ArrayList, // 那我們就建立一個不帶泛型標記的ArrayList // (有標記的就是一開始的寫法) // 編譯加執行成功!! ArrayList<JMenuItem> gat3[] = (ArrayList<JMenuItem>[])new ArrayList[10]; for (int i=gat3.length-1; i>=0; --i) gat3[i] = new ArrayList<JMenuItem>(5); System.out.println("gat3[1].size()="+gat3[1].size()); // 轉型少了泛型也是可以的,因為隱含轉型也合法。 // 同樣的,編譯加執行成功!! ArrayList...

宣告與初始化陣列成員與類別成員

先前資訊安全的作業Java的AES程式,想改為想使用BCB改為C++版實作,在改變實作語言時遇到小trouble,我有下面一個只擁有常數資料的類別: public class AESTables {  public static final byte[] Sbox = {   (byte)0x63 ,(byte)0x7c ,(byte)0x77 ,(byte)0x7b ...  }  ... } 而直接的想法是下面這個樣子,我認為這樣應該就OK了(嘆) class AESTables {  public:  static const unsigned char Sbox[] = {   0x63 ,0x7c ,0x77 ,0x7b ...  }  ... } 結果是沒有辦法compile,我try'n'error許久,最後的結論是只有下面這樣才能compile。 class ts {  public:  const static int a = 10;  const static int b[]; }; 但是這樣只能宣告成功,卻沒辦法使用它,一使用就會產生LinkError。而想要利用default constructor初始化陣列,compiler則是會給予const存取拒絕或認定為不正常的語法。 最後在 Google 上找到 解決方案 了,不過老實說,這方法沒有寫過還真不知道它存在。 class ts {  public:  const static int a = 10;  const static int b[]; const static ClassC c; }; const int ts::b[] = {1, 1, 1, -10, -1}; const ClassC ts::c = ClassC(); const ClassC ts::c(); //簡寫 使用關鍵字: C++ static class member array initialization 2007-10-01 備註 今天在以前買的 參考書 中也看到相同寫法了,由此可見以前都沒學好(汗)。

Java Puzzlers: 22. Dupe of URL

這隻程式會做什麼事情? public class BroswerTest { public static void main(String[] args) { System.out.println("iexplore"); http://www.google.com.tw System.out.println(":maximize"); } } 看出來了嗎? 其實它只會印字而已。 讓我們排版一下,這樣應該就瞭解了 public class BroswerTest { public static void main(String[] args) { System.out.println("iexplore"); http: //www.google.com.tw System.out.println(":maximize"); } } http: 是個label,在Java中也是有Label,是用在loop跳出時指定用的。 而// 則是整行註解,把後面的東西都註解掉了,所以這個URL可以編譯其實只是個假象。 上一篇Puzzlers: Java Puzzlers: 38.The Unwelcome Guest

Java 小程式:AES加解密實作

這是大三的資訊安全導論的期末Poject,雖然是以組為單位作的Project,但是本組只有我的期中考分數很差,分數是落在底標的部份,知道分數以後我就趕快的將期末這個Project搞好,期望倚靠程式Project得個高分,來彌補其中考的低分:P AES 的鎖鑰產生器 AesKeyGenerator 實作了亂數產生鎖鑰與指定密碼長度建立鎖鑰的方法。 AES 的抽象加解密器 AbstractAesCryptor 實作了AES的一個加密單位State的加解密方法,加解密流程則需自行實作。 這份程式碼出來的已是我改寫過的版本了,之前寫的更是錯綜複雜。至於之後的加密流程,如:ECB、CBC、CTR等等,由於寫的實在不好,都和GUI介面的綁在一起,就不獻醜了。 2018/05/02 因為太多人會點我上面的文件想要參考,雖然code滿亂的,但是我還是把它放上github了。 https://github.com/Mirochiu/CollegeAssignments/tree/master/AesCryptor

C與C++:展開前置處理的內容

gcc的-E選項可以將前處理(pre-processing)過後的程式碼印在螢幕上, 就是說所有的巨集與引入(include)都會被展開, 練習寫巨集的時候,可以用這個選項看到處理過後的結果, 或是發現一些程式碼的錯誤訊息所指出的位置與程式碼的行數不一樣, 也可以用來查看為何會有產生錯誤的訊息。 另外,配合管線的使用就能夠將資訊寫入到檔案中 EX:gcc -E main.c > main.pp gcc(1): GNU project C/C++ compiler - Linux man page

為什麼有些主程式(main)有三個參數?

為什麼有些main主程式會有三個變數在參數列上? 這個問題在書上有時會被提及,但是通常都不作說明,或要求你去查閱其他資料或使用手冊。在GNU C library第25章Program Basics中有詳細的說明,許多剛踏入Linux作程式的新手們都應該詳細閱讀此章的基礎知識。 其實 第三個參數就是系統環境變數 ,執行程式時由系統直接傳遞給程式,我們可以利用這個變數客制化我們的程式本身,得到多數程式放置的位置、常用的分隔符號、主系統檔案位置等等。在Linux系統上,有工具是依照這些環境變數來工作的,並依此變化出許多特殊的使用方法。 以下為 GNU C Library 25.1 的原文說明: 25.1 Program Arguments The system starts a C program by calling the function main. It is up to you to write a function named main—otherwise, you won't even be able to link your program without errors. In ISO C you can define main either to take no arguments, or to take two arguments that represent the command line arguments to the program, like this:  int main (int argc, char *argv[]) The command line arguments are the whitespace-separated tokens given in the shell command used to invoke the program; thus, in `cat foo bar', the arguments are `foo' and `bar'. The only way a program can look at its command line arguments is via the arguments of main. If main doesn...

紀錄: VIM簡單操作

VIM有很多種模式,而且操作指令都是區分大小寫的,也就是說若指令為abc,則不能打成Abc、ABC、abC等,這點請牢記。 剛進入VIM是「一般模式」,只要一直按Esc,就會回到這個模式。 輸入冒號就代表你要輸入指令,會切換到「指令模式」 在VIM中開啟某檔案 :e 檔案名稱 輸入檔案名稱時,有tab自動完成的功能。記憶方法: E dit 離開VIM(會提醒存檔) :q 記憶方法: Q uit 強制離開VIM(不存檔) :q! 寫入檔案後離開VIM :wq 指令的順序很重要,若打成:qw就只是離開VIM。記憶方法: W rite 強指寫入檔案後離開VIM :wq! (到底有沒有這個這個指令我機會沒使用) 除了指令以外,還有一些操作 往後搜尋 /要搜尋 是緊接著,跟Linux的man搜尋功能一樣。 往前搜尋 ? 往前與往後搜尋都可以用n作直接搜尋,或是只輸入/或?繼續搜尋,或改變搜尋方向。 複製我一直記不太起來,因為是yy, 原本的意義 是 y ank(拔罐), 貼上則是p 刪除一行為dd 另外還有.是重作上一個指令 要編輯文字內容,則要進入「插入模式」,我是輸入i進入這個模式, 輸入數字時,不要用鍵盤右邊的數字鍵面( NUMPAD ),VIM只會把它當作其他的功能鍵。 延伸閱讀 Jserv's blog: vi / vim 圖解鍵盤指令 大家來學 Vim 一個歷久彌新的編輯器

Algorithm:Xor交換兩個數值變數

這是我今年春節看Java Puzzlers時才知道的技巧,有很大的delay,交換數值變數利用Xor運算就可以完成,就方法就。 b^=a; a^=b; b^=a; 這是利用xor的特性,將A xor B 或是 B xor A都會得到一個相同的值 C。若將這個值跟 A 作xor運算,就會得到 B;而若是將其跟 B 作xor運算,則會得到 A。 A xor B = C C xor B = A C xor A = B 在密碼學中,資料與key的混合也常常用xor運算達到還原的效果。 這個方法的優點是不消耗額外記憶體空間,只需要a和b兩個變數即可完成。 程式碼如下: #include <stdio.h > #include  < stdlib.h > int main() {     int x = 10;     int y = 20;     printf ("origin: x=%d, y=%d\n", x, y);     x = x ^ y;     y = x ^ y;     x = x ^ y;     printf ("swap:   x=%d, y=%d\n", x, y);     return 0; } https://en.wikipedia.org/wiki/XOR_swap_algorithm 延伸連結 (原創) 如何交換兩個變數,而不動用第三個變數? (C/C++) (C#) - 真 OO无双 - 博客园 達可鴨的池塘: XOR奇文共賞─變數直接互換、無線網路編碼

Java: 視窗置中的方法

假設JFrame的實體是frame,則可以用下面兩種方法使視窗置中 方法一、利用Toolkit類別取得螢幕大小後,再計算出JFrame中間的位置 java.awt.Dimension scr_size = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); frame.setLocation( (scr_size.width - frame.getWidth()) / 2, (scr_size.height - frame.getHeight()) / 2); 使用這個方法的缺點,是必須要先設定好視窗的寬高屬性,或是仙呼叫pack方法自動設定,否則就沒辦法使視窗顯示在螢幕中央。 方法二、利用JFrame的其中一個方法 frame.setLocationRelativeTo(null); 這個方法我還是頭一次知道,而且這方法還不是新的API所增加的,在Java Document 1.4中久已經有描述, JFrame.setLocationRelativeTo(Component) ,只要將參數給null值,就可以使視窗置中,而且 Java Tutorial 也有提到用這個方法。

Java: 反鋸齒繪圖 Paint with graphics using anti-aliasing

圖片
大一的時候寫小遊戲時,發現Java顯示出來的大型中文字怎麼都不甚美觀,文字邊會有鋸齒狀,應該像遊戲一樣要 anti aliasing 一下才對嘛?可是到底要怎麼用,當時就沒繼續研究下去,直到今天才無在 小範例 中發現到它,都過這麼久了說起來還真是汗顏。 實際效果 範例程式碼 import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import javax.swing.JPanel; import javax.swing.JFrame; public class UnicodeText { public static void main(String[] args) { JFrame frm = new JFrame("反鋸齒效果 demo"); JPanel jpn = new JPanel(){ public void paint(Graphics g) { super.paint(g); Graphics2D g2 = (Graphics2D) g; Font Anit = new Font("Monospace", Font.PLAIN, 62); g2.setFont(Anit); g2.drawString("沒用反鋸齒!!", 10, 50); Graphics2D g2d = (Graphics2D)g; g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.drawString("使用反鋸齒!!", 10, 145); } }; frm.add(jpn); frm.setSize(350,200); frm.setResizable(false); frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frm.setVisible(true); } } 重要的就只是兩行,將Graphics強制轉成Graphics2D,...