<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    我的隱式生活(My Implicit Life)

    繼續搞“對象”,玩OO.

    首頁 新隨筆 聯系 聚合 管理
      11 Posts :: 1 Stories :: 39 Comments :: 0 Trackbacks

    2006年3月14日 #

    近期寫了個電子書的C/S模式的下載工具,一個server端,一個client端。

    目的就是想在公司能很方便的訪問家里那些收集很久電子書,方便查閱。

    用了1,2個星期,雖然寫的很爛,但是沒有用任何第三方的產品(server or db)。

    現在里面的書籍已經接近200本了。

    注:server就用了家里的adsl,所以速度慢,關閉不定時。畢竟玩玩嘛。

    有興趣的朋友先裝個jdk1.5。再運行下面壓縮包里的exe文件執行即可。

    點此下載

    User ID:???????????????blogjava
    Password:???????????? blogjava
    ?

    posted @ 2006-10-15 13:21 marco 閱讀(3472) | 評論 (9)編輯 收藏

    Java Collection Framwork中的類的確是最重要的基礎api,實現任何算法,基本上都很難離開它。

    因此理解這堆“集合(Collection)類”很有必要。聲明一下,以前一直都是叫它們集合類,但是好像Think In Java的作者鄙視了這個說法,嚴格的說應該叫Container類,而后看了它整整一章書以后,覺得還是人家說的有道理。

    它說這個container類庫,包含了兩大類,Collection和Map,而Collection又可以分為List和Set。當然這些抽象概念都被定義成了接口。

    話說,這樣的分類的確是嚴格按照類之間的繼承關系來說得,但是俺總覺得很別扭,真動手的時候,還是很難選擇。當然,Anytime and Anywhere使用ArrayList絕對都能解決問題,但這樣做畢竟太農民了一點。

    所以,我自己有了一些想法。先回歸到最基本最基本的數據結構的層面,管你是Collection還是Container,反正描述的都是一堆東西吧。數據結構第一章講了一個結構:在物理上連續分配空間的順序結構,叫順序表(希望記性是好的),而離散分配空間的,應該叫做鏈表,最常用的就是單鏈表。這兩個東西,其實就是很多復雜數據結構的基礎,還記得嗎,當時就是講完這些東西,才開始講棧、隊列、二叉樹、有向無向圖的。所以,這個順序結構是很基礎的。而在JAVA中,順序表對應的就是List接口,而一般順序表就是ArrayList(有效進行隨機index查找);而單鏈表就是LinkedList(有效進行插入和刪除),兩個的優劣當年都講爛了,這里就不說了。

    有了這兩個結構以后,JAVA就不提供Stack和Queue單獨的類了,因為,用戶可以用上面兩個類輕易的去實現。

    那Set和Map有怎么跟List連上關系呢?

    我認為可以把它們看成是無序和單一的List(Map只是兩個有映射關系的List罷了)。

    Set和Map無序和單一的特性,決定了它們天大的需求就是根據關鍵字(元素對象)檢索。so,為了效率,必須hash。

    有了HashSet和HashMap。

    同時,如果非要保持住元素的順序,有了LinkedHashSet、LinkedHashMap。


    結論:

    假如你的需求是
    1:往Container中放的對象是無序且單一的;
    2:經常要檢索。
    用HashSet或HashMap吧。

    ps:這兩個條件其實是一回事,因為如果是不單一的話,你去檢索它干嘛。

    如果進而需要保持元素的順序,不要讓他順便iteration,那就選擇LinkedHashSet和LinkedHashMap。

    假如你的需求不滿足以上1&2,那你放心,List肯定能幫你解決,你只要稍微想一下是ArrayList好還是LinkedList好。

    題外話:

    關于Hash,務必記得要讓自己的元素對象override hashCode()和 equles() 方法,要不你直接可以洗了睡。

    關于所有這些Container,務必記得有個輔助類叫Interator,遍歷盡量要用它。

    關于一些老的Stack、Vector、HashTable,聽說以后不要用了哦。收到啦!!

    posted @ 2006-09-20 16:53 marco 閱讀(2325) | 評論 (0)編輯 收藏

    任何信息,基本都是以文字的形式傳播和記錄下來的。

    在計算機中,文字就是字符的集合,也就是字符串,C就是因為對字符串設計的不好,才那么容易溢出。而別的一些高級語言,對于這個進行了很多的改進。

    編程的人由于技術方向和應用方向的不同,日常編程的內容差距很大。但是對于字符串的處理,那可是永遠都避不開的工作。

    昨天跑步的時候,想了一下,對于字符串的操作有那么多(search,match,split,replace),感覺很煩雜,能不能抓住這些操作的一個基本集?

    不知道對不對,反正想出來了一個,這個基本操作就是search,這里的search的意思是:在輸入串中找到目標串的開始位置(start index),和結束位置(end index)。

    有了這個基本集,別的操作都很好衍生出來:

    局部match:其實就是要求search操作至少返回一個start index。

    全match:其實要求search操作的至少返回一個start index,并且start index要為零,end index要為輸入串的全長。

    split:其實就是search操作之后,把前一個end index和當前的start index之間的字符串截出來而已。

    replace:其實就是search操作之后,把start index和end index之間的字符串換成另外的而已。

    所以,歸根到底,都是一個search操作的拓展罷了。這么一想,感覺清晰多了。

    這么一來,API對search的能力支持的好壞和效率高低是衡量字符串操作功能的標準,當然,如果有直接支持match,split,replace操作的話就更好了。

    java對字符串search的支持,最基本的就是下面的String的indexOf方法:

    int indexOf(String str)
    ????????? Returns the index within this string of the first occurrence of the specified substring.

    這里我想說的是,很多時候我們所謂要search的目標串,根本就不是固定單一的,而是變化多樣的。如果只有一兩種情況,最多用兩次上面的方法唄。但是有些情況是近乎不可能羅列的,例如,我們講的代表email的字符串,我們不可能遍歷它吧。

    所以,需要一種能夠通用表達字符串格式的語言。這就是Regular Expression(re)。

    假如上面方法indexOf的str參數能支持re做為參數的話,那對于這種多樣的search也可以用上面的方法了。

    可惜,indexOf不支持re作為參數。

    so,以下就介紹java api中可以用re作為參數的字符串操作方法(參數中的regex就是re)。

    --------------------->>
    String類的:

    全match操作:
    boolean matches(String regex)
    ????????? Tells whether or not this string matches the given regular expression.

    全replace操作:
    String replaceAll(String regex, String replacement)
    ????????? Replaces each substring of this string that matches the given regular expression with the given replacement.

    首個replace操作:
    String replaceFirst(String regex, String replacement)
    ????????? Replaces the first substring of this string that matches the given regular expression with the given replacement.

    全split操作:
    String[] split(String regex)
    ????????? Splits this string around matches of the given regular expression.


    有限制數的split操作:
    String[] split(String regex, int limit)
    ????????? Splits this string around matches of the given regular expression.

    <<---------------------

    可惜啊,可惜,可惜java的String類里面沒有可以支持re的search方法,那如果要用re來search,只好使用java中專門的re類庫。

    java中的re類庫主要就兩個類,一個叫Pattern,顧名思義,代表re的類。一個叫Matcher類,反映當前match狀況的類(如存放了當前search到的位置,匹配的字符串等等信息)。

    一般在構造中,“re的表達式”作為參數傳遞入Pattern類,“輸入串(待過濾串)”作為參數傳遞入Matcher類。

    然后使用Matcher類的字符串search方法就可以了。Matcher真正提供search功能的API叫find。下面列出。
    --------------------->>
    Matcher類search操作相關的方法:

    boolean lookingAt()
    ????????? Attempts to match the input sequence, starting at the beginning, against the pattern.

    boolean matches()
    ????????? Attempts to match the entire input sequence against the pattern.

    boolean find()
    ????????? Attempts to find the next subsequence of the input sequence that matches the pattern.

    String group()
    ????????? Returns the input subsequence matched by the previous match.

    <<---------------------

    前三個都是search方法,返回成功與否。第四個是返回當前search上的字符串。

    ok,至此。使用re的search操作也有眉目了。

    當然,Pattern和Matcher也包含直接使用re進行的match,split,replace操作。

    --------------------->>
    Patter類別的字符串操作方法

    全match操作:
    static boolean matches(String regex, CharSequence input)
    ????????? Compiles the given regular expression and attempts to match the given input against it.

    全split操作:
    String[] split(CharSequence input)
    ????????? Splits the given input sequence around matches of this pattern.

    有限制數的split操作:
    String[] split(CharSequence input, int limit)
    ????????? Splits the given input sequence around matches of this pattern.


    Matcher類別的字符串操作方法

    全replace操作:
    String replaceAll(String replacement)
    ????????? Replaces every subsequence of the input sequence that matches the pattern with the given replacement string.

    首個replace操作:
    String replaceFirst(String replacement)
    ????????? Replaces the first subsequence of the input sequence that matches the pattern with the given replacement string.

    動態replace(replacement可以根據被替代的字符串變化而變化)
    Matcher appendReplacement(StringBuffer sb, String replacement)
    ????????? Implements a non-terminal append-and-replace step.

    StringBuffer appendTail(StringBuffer sb)
    ????????? Implements a terminal append-and-replace step.

    <<---------------------

    總結:
    當必須使用re的時候,search操作就要用到Pattern,Matcher,當然動態的replace操作也要用到這兩個類。而別的match,replace,split操作,可以使用pattern,Matcher,當然也可以直接使用String,推薦還是用回咱們的String吧。

    注:以上都是看jdk1.4以上的文檔得出的結論,以前版本不能用不負責任。

    posted @ 2006-08-31 15:13 marco 閱讀(2692) | 評論 (0)編輯 收藏

    創建和銷毀對象

    重點關注對象的創建和銷毀:什么時候、如何創建對象,什么時候、什么條件下應該避免創建對象,如何保證對象在合適的方式下被銷毀,如何在銷毀對象之前操作一些必須的清理行為。

    嘗試用靜態工廠方法代替構造器

    如果一個 client 要實例化一個對象來使用,傻 b 都知道應該先調用類的構造器來 new 一個對象,之后再調用相應的方法。除了這個方式, Java Effective 還建議了另一種方法:用靜態工廠方法來提供一個類的實例。以下的例子不反映兩者的優劣,只是反映兩者在代碼實現上的不同,優劣之后再談:

    假設咱們要一個顏色為黑色、長度為 50cm 的錘子,自然就用構造器創建一個

    Hammer myHammer =? new Hammer(Color.BLACK, 50);

    而用靜態工廠方法來實例化一個對象,如下

    Hammer myHammer = Hammer.factory(Color.BLACK,50);

    也可以用專門的一個工廠類來實例化

    Hammer myHammer = Toolkit.factory(“Hammer”, Color.BLACK,50);??

    單純從上面的代碼上看,真的只有傻 b 才會選擇靜態工廠的方法,完全就是多此一舉,直接 new 又快又爽,搞這么麻煩做莫斯(武漢話“什么”的意思)?

    別急,別急,你急個莫 b (武漢粗話:基本就是“你急個毛”的意思)?

    下面就說說用靜態工廠代替構造器的好處( advantage )和不好處( disadvantage )。

    第一個好處,講你都不信,行家們認為,構造器有一個不好的地方就是:這個方法的簽名( signture )太固定了。

    構造器的名字是固定的,生個 Hammer ,構造器的名字就是 Hammer (……),唯一能變化的地方就是參數,假設我的這個錘子有兩個很變態的構造需要:

    1 :第一個參數是顏色( Color 型),第二個參數是錘子頭的重量( int 型)。

    Hammer Color c, int kg {

    //remainder omited

    }

    2 :第一個參數是顏色( Color 型),第二個參數是錘子的長度( int 型)。

    Hammer Color c, int cm {

    //remainder omited

    }

    感覺滿足需要了,但是細心一看,完了,構造器的參數列表類型重復了,肯定編譯通不過,這是面向對象構造器天生的缺陷——唯一的變化就是參數,參數都分辨不了,就真的分辨不了。

    而另外就算參數能分辨的了,構造器一多,它的參數一多,您根本就不知道每個參數是用來干什么的,只能去查閱文檔,在您已經眼花繚亂的時候再去查文檔,一個一個的對,折磨人的活。

    這個時候,您就可以考慮用靜態工廠方法來實例化對象了。因為靜態工廠方法有一個最簡單的特點就是:他有可以變化的方法名(構造器的名字變不了)。用名字的不同來代表不同的構造需要,這么簡單的普通的特點在這里就是它相對于構造器的 advantage

    如上面的錘子的例子可以這樣:

    1 Hammer.produceByWeight (Color c, int kg){

    //remainder omited

    }

    2 Hammer.produceByHeight (Color c, int cm){

    //remainder omited

    }

    這是不是一目了然多了。嗯,我是這樣認為的。

    第二個好處,“靜態工廠方法不需要每次都真的去實例化一個對象”——其實這也是另一些優化方法的前提。

    構造器的每次 invoke 必定會產生一個新的對象,而靜態工廠方法經過一定的控制,完全可以不用每次 invoke 都生成一個新的對象。

    為什么不每次都生成一個對象的原因就不必說了,因為原因太明顯。這個原因就是為什么要“共享”對象的原因。

    下面講講通常使用的兩種共享具體策略,也就是具體方法了:

    1 :單例模式的需要,一旦需要某個對象有單例的需要,必定對于這類對象的構造只能用靜態工廠方法了。

    2 flyweight 模式和不變( immutable 模式的需要,這兩個模式很多時候都說一起使用的,一旦一些對象我們認為是不變的,那自然就想拿來重用,也就說共享,而 flyweight 就是用來重用這些小粒度對象的。

    Boolean.valueOf (boolean) 方法:

    Boolean a = Boolean.valueOf (100);

    Boolean b = Boolean.valueOf (100);

    ?a,??b兩個引用都是指向同一個對象。

    這些對象都是不變的,而 valueOf 的控制就是用的 flyweight 方法。

    這種一個狀態(如上面一個數字)對應的對象只有一個還有一個好處,就是可以直接通過比較“引用”來判斷他們是否 equel (這里的 equel 是邏輯相等的意思),以前需要 a.equels(b) ,而一旦用“ flyweight 模式和不變( immutable 模式”后,避免了產生多余的相同對象,用 a==b 就可以達到 a.equels(b) 的目的了。這樣當然優化了 performance ??

    第三個好處,其實就是工廠方法的核心好處——我把它稱為“抽象類型構造器”。它可以為我們提供一個抽象類型的實例,同時必要的隱藏了抽象類型的具體結構。這是 new 怎么都達不到的。

    這種模式的好處其實就是面向對象的最核心的好處,抽象和具體可以分離,一旦抽象定義好了,具體的東西可以慢慢的變化,慢慢的拓展——開閉原則。

    Collections Framework API ,都是描述集合類型的接口,也就是對于客戶端來看,只有 Collection 這個類要認識,而實際上,實現這個接口的 Collection 是多種多樣的。如果要讓用戶都知道這些具體實現的 Collection ,就增加了復雜度。

    這時,通過一個靜態工廠方法,就可以隱藏各種 Collection 的具體實現,而讓 Client 只使用返回的 Collection 對象就可以了。

    這里還可以加上一些權限控制,如這些實現只要對于工廠來講是可以訪問的,不用是 public 的,而他們只要通過 public 的工廠就可以提供給用戶。非常有利于代碼的安全。

    靜態工廠方法的第一個缺點就是:使用靜態工廠方法創建的類的構造器經常都是非公共或非 protected 的。 這樣,以后這些類就沒有辦法被繼承了。不過也有人說,不用繼承就用 composition 唄。也是!呵呵。

    靜態工廠方法的第二個缺點是:在 jdk 文檔里,這些靜態工廠方法很難跟別的靜態方法相區別。 而文檔中,構造器是很容易看到的。

    為了一定程度解決這個問題,我們可以用一些比較特別的名字來給這類靜態工廠方法來命名。最常用的有:

    valueOf —— 用來放回跟參數“相同值”的對象。

    getInstance —— 返回一個對象的實例。單例模式中,就是返回單例對象。

    總結:靜態工廠方法和構造器都有各自的特點。最好在考慮用構造器之前能先考慮一下靜態工廠方法,往往,后者更有用一點。如果權衡了以后也看不出那個好用一些,那就用構造器,畢竟簡單本分多了。

    posted @ 2006-07-15 12:35 marco 閱讀(626) | 評論 (0)編輯 收藏

         摘要: 關鍵字:Observer Pattern、Java Thread、Java Swing Application 1 近來的閱讀 近來寒暑不常,希自珍慰。武漢天氣不是狂冷,就是狂熱,不時還給我整個雪花,就差冰雹了。   自己做的事吧,也沒有什么勁兒。看看自己喜歡的東西,等著希望中的學校能給我offers(是復數),看著自己想去又不想去的公司的未來同事在群里面幻想未來的樣子,別操你大...  閱讀全文
    posted @ 2006-03-14 01:51 marco 閱讀(2603) | 評論 (2)編輯 收藏

    主站蜘蛛池模板: 亚洲夜夜欢A∨一区二区三区| 无码欧精品亚洲日韩一区夜夜嗨 | 亚洲人色大成年网站在线观看| 青青操免费在线视频| 久久亚洲国产成人精品无码区| 人人公开免费超级碰碰碰视频 | 福利免费在线观看| 91免费在线播放| 亚洲无人区视频大全| 无码人妻一区二区三区免费手机 | 国内成人精品亚洲日本语音| 99免费视频观看| 亚洲第一页中文字幕| 成人网站免费观看| 国产成人精品日本亚洲语音 | 亚洲精品无码成人片久久| 性色午夜视频免费男人的天堂| 无码乱人伦一区二区亚洲一| 很黄很黄的网站免费的| 亚洲人成欧美中文字幕| 99视频在线免费看| 亚洲人成影院77777| 国产99视频免费精品是看6| 日日摸夜夜添夜夜免费视频| 亚洲精品夜夜夜妓女网| 久久久久久曰本AV免费免费| 亚洲国产精品无码专区| 亚洲免费一级视频| 国产亚洲精品国产福利在线观看| 国产成人亚洲综合无码| 亚洲精品视频在线观看免费| 日本亚洲欧美色视频在线播放| 亚洲日韩激情无码一区| 无码国产精品一区二区免费虚拟VR| 亚洲狠狠婷婷综合久久蜜芽| 在线亚洲精品福利网址导航| 美丽的姑娘免费观看在线播放| 亚洲av无码专区在线电影天堂| 黑人大战亚洲人精品一区| 无码中文在线二区免费| 国产精品高清免费网站|