<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>青雉</title>
    <description>万里长城十亿兵，
国耻岂待儿孙平。
愿提十万虎狼骑，
越马扬刀入东京。</description>
    <link>http://yuhlster.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>回复North</title>
        <author>青雉</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yuhlster.javaeye.com">青雉</a>&nbsp;
          链接：<a href="http://yuhlster.javaeye.com/blog/25339" style="color:red;">http://yuhlster.javaeye.com/blog/25339</a>&nbsp;
          发表时间: 2006年09月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          不好意思。一直没回复。这个bolg有问题啊。怎么不能回复啊。我一回复就没反应了。<br /><br />我都崩溃了。<br /><br />import static java.lang.Math.random; //程序开头处 <br />//引入类<br />import java.lang.Math; //程序开头处 <br />//引入静态方法<br />这样我们在调用方法的时候就不用写类的名称了。<br />double b = random();<br />不过这样就会影响可读性了。<br /><br />我说的有不对的，请指教。
          <br/>
          <span style="color:red;">
            <a href="http://yuhlster.javaeye.com/blog/25339#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 30 Sep 2006 07:51:37 +0800</pubDate>
        <link>http://yuhlster.javaeye.com/blog/25339</link>
        <guid>http://yuhlster.javaeye.com/blog/25339</guid>
      </item>
      <item>
        <title>Jdk 6 , 野马, 新特性预览</title>
        <author>青雉</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yuhlster.javaeye.com">青雉</a>&nbsp;
          链接：<a href="http://yuhlster.javaeye.com/blog/25272" style="color:red;">http://yuhlster.javaeye.com/blog/25272</a>&nbsp;
          发表时间: 2006年09月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          今天早上来看到了6.0的特性。收藏了。<img src="/images/smiles/icon_biggrin.gif"/><br />初探Java SE 6： 一个桌面赢家<br /><br />一个有着丰富的Java经验的开发者试用了一下Java SE 6 Beta，并且认为Java SE 6 有希望成为桌面开发的一次革命。<br /><br />by Eric Bruno (Translated by Xu Ting)<br /><br />刚刚发布的Java Standard Edition 6 （Java SE 6，也被称为Mustang）beta版完整的包括了预定的新特性，对于主流的应用来说，已经足够稳定。我在第一时间下载并尝试了这个新?动物?，并且被它全新的桌面特性所震撼。除了Java平台一贯以来的命名方式上的改变(去掉了2)，它还包含了包含了很多值得探索一下的新特性。这些新特性可以分为两类：桌面和核心。<br /><br />桌面上的改进主要集中在用户界面(UI)性能，以及，用本地化的接口与OS的桌面整合。核心部分则集中在提高开发人员的生产性，以及Java程序的可管理性上。Sun的Mustang团队也对Web Service以及安全性方面作出了显著的改进。<br /><br />不管怎么样，无论你是一个应用程序开发人员，还是一个系统管理者，或者提供独立的工具，或者是一个安全专家，Java SE 6都为你准备了些东西。这片文章主要是详细讨论了一些我试用过了的有趣的特性。<br /><br />有关Java核心的新特性以及改进。<br /><br />关于Java 核心部分，我们认为是部分((语言和工具)对所有的Java而言都是很基础的东西，包括从界面API到服务端API库。下面我将按照不同的分类来讨论这些与Java核心相关的特性。<br /><br />开发人员的生产性<br /><br />新的Java编译器API允许你从一个Java应用程序中去编译另外的Java源程序。在这样的编译的过程中，应用程序将根据计算出来的依赖关系去访问那些相关的API库文件，这个过程也会产生Warning，Error以及其他一些在编译的时候会产生的消息。虽然这个功能是我不太会常去用的，但是我很快发现了一种用法。比如：我在我的应用程序A中，快速的用这个特性来编译A的数据访问层代码。我可以用我的代码去生成并且编译我在A程序中要去访问的数据库表的类，最终的结果可以是一个从Ant脚本中生成出来的JAR文件。这样最显而易见的一个事实就是我可以在自己的程序中去重新编译生成这些重要的文件，至少我可以不需要改动应用程序。<br /><br />Java Scripting，是在Java SE6中实现了的JSR223。这是一个脚本框架，提供了让脚本语言来访问Java内部的方法。你可以在运行的时候找到脚本引擎，然后调用这个引擎去执行脚本。这个脚本API允许你为脚本语言提供Java支持。另外，Web Scripting Framework允许脚本代码在任何的Servlet容器（例如Tomcat）中生成Web内容。<br /><br />对于调试，Java平台的调试器(JPDA)已经提供了死锁诊测，并且可以为产生了死锁的对象生成堆栈信息。另外，Java SE 6允许在一个运行中的JVM上，添加不同的诊断工具 。<br /><br />应用程序管理<br /><br />Java SE 6中对内存泄漏增强了分析以及诊断能力。当遇到java.lang.OutOfMemory异常的时候，可以得到一个完整的堆栈信息，并且当堆已经满了的时候，会产生一个Log文件来记录这个致命错误。另外，JVM还添加了一个选项，允许你在堆满的时候运行脚本。(这也就是提供了另外一种方法来诊断错误)<br /><br />增强的JMX 监视API在MBean的属性值传入了一个特定的参数的时候，允许这个应用程序发送一个事件通告。（这里的属性值可以在很复杂的类型中）<br /><br />对于Solaris 10的用户，为Solaris提供的Hotspot JVM中，提供了一种通过Solaris DTrace(这是个系统的调试工具)来追踪显示JVM内部的活动情况，包括垃圾收集，类装载，线程，锁等等。我在JavaOne上得到了一个第一手的 DEMO，这个DEMO所显示的能追踪到的详细情况简直是太棒了。比如，当一个应用程序运行的时候，DTrace允许可以在任何地方中止代码，查看所有被载入内存的库(不仅仅是Java的类库，甚至是系统级别的库)，并且可以单部跟踪到Solaris的内核中去，甚至可以直达硬件！Java新提供的这个工具为全世界提供了一种系统级别的追踪调试手段。我还记得以前我在Solaris的JVM上经常会收到一些Signal8这样的错误，这个特性将会省去我许多的猜测。<br /><br />Web services<br /><br />Java SE 6 包含了一些支持Web Services的新API。XML 数字签名API，允许你为基于Java上的Web Services数据提供加密的可能。Java-XML Web Services (JAX-WS)2.0API更新的以前称为JAX-RPC的API库。增强的Java-XML Binding (JAXB)2.0包含了对XMLSchema的支持，以及将某个Class绑定到一个Schema上去。最后， Streaming API for XML (STaX)提供了一个双向API，这个API可以通过一个事件流来读取或者写入XML，其中包括跳过某个部分，然后直接关注与文档中的另外一个小部分的能力。<br /><br />安全<br /><br />Java SE 6的安全部分，整合了GSS/Kerberos的操作API，LDAP上的JAAS认证，以及一个?请求安全认证?的框架，这个框架允许应用程序从一系列的协议中选择一种?请求安全认证?所用的协议。<br /><br />桌面特性以及改进<br /><br />Java长久以来，一直被认为是一个一流的服务器端软件的语言，但是桌面GUI应用上只能是二流地位。 Sun的Java桌面工作小组正在努力改变这个现状。通过调用系统的GUI接口，来更好的显示Java 的GUI应用。他们的努力不仅改善了Java SE 6中的GUI性能，也改变了一些Java GUI应用程序的行为。(比如提供了DnD的支持)<br /><br />Java SE 6中的桌面新特性，大部分 都来自于JDesktop Integration Components（JDIC）项目。JDIC项目为Java的应用程序提供了访问OS底层本地桌面GUI接口的方法，例如浏览器，Email编辑器，文件类型绑定，系统托盘，阴应用程序启动，打印等等。 下面是那些Java SE 6中最显著的一些桌面特性。<br /><br />    * 启动界面的支持。启动界面(Splash Screens)是一个应用程序启动的时候，用户等待的时候给用户看的界面。Java SE 6中的启动界面甚至可以在JVM启动之前显示出来。<br />    * JFC以及Swing中的改进：<br />          o Java SE 6通过调用Windows的API，不仅提高了 GUI的性能，也保证了在当前以及以后的Windows版本中的兼容<br />          o 增强的布局管理包含了一个可定制的布局管理，另外还包含了一些使得GUI元素布局的时候更加简单的方法。<br />          o Java SE 6中显著的增强了Swing控件的托拽功能，并且是可以定制的。<br />          o 真正的双缓冲，提供了快速，平滑的图形效果。<br />    * 系统托盘的支持。在java.awt包中，增加了SystemTray和TrayIcon两个类，它们允许你在Windows或者使用GNome 的Linux的系统托盘区，添加图标，提示信息，弹出菜单。系统托盘区是所有的应用程序都共享的区域，通常在屏幕的右下角。通过系统的动作和事件可以允许你的Java应用程序去相应在托盘区的鼠标事件。我发现这个特性也同样对我的服务器程序非常有用，比如，我可以通过桌面API，非常轻松的启动一个浏览器，并且打开这个服务器程序的管理界面(当然，是HTML页面)。在Linux或者Window上，我再也不需要自己输入管理界面的URL和端口号了，只要简单的点击一下托盘图标就可以:)<br />    * JTable支持打印了<br />    * Java 2D方面增强了许多。 主要是在字符显示上，尤其在LCD的显示屏上。整合了许多字体反锯齿的设定来保证平滑的显示文字。<br />    * 新的java.awt.Desktop包。Java SE 6中这个新的包目标是让Java 的GUI应用程序成为?一等公民?。有了这个包，Java的应用程序可以启动默认的浏览器和邮件客户端，并且整合了一些通用桌面应用程序的启动。例如启动OpenOffice，然后打开，编辑，打印一些制定的类型。Desktop包通过action事件来实现的，你可以将这些Action整合到你的应用程序中去。<br />    * 国际化。Java SE 6提供了一些本地化特性的可扩充性，比如日期格式，Unicode文字的一致性，资源簇等等。<br /><br />一场Java桌面革命<br /><br />Java SE 6提供了许多的特性，改进，bug修改等 (这些可以参考我的另外一篇翻译)，本文旨在对Java这个即将到来的重要版本之前做一个历史的记录。 这个改动涉及到了Java SE如此多的方面，乃至几乎所有的Java应用程序都会被波及到，包括那些Java EE的应用程序。<br /><br />Java SE 6有潜力成就一场桌面革命，就如同Java 2成就了一场服务器革命。最好是现在就为这场即将到来的风暴做好准备，让你自己成为革命的先锋人员。<br /><br />Eric Bruno is a New York-based consultant who has built high-volume Web applications, database systems, and real-time transactional systems in Java and C++. Visit www.ericbruno.com for more about him.<br /><br />Posted in Java Tech | No Comments »<br />New features in Java SE 6.0<br />Monday, March 6th, 2006<br /><br />A few days ago, Sun just released Java SE 6.0 Beta. And I had viewed the release notes and some articles discussed the new features .<br /><br />Here is a translation about the new features and enhancement list provided by Sun officially. And I had translated this to Chinese(Simplified Chinese.)<br /><br />The original document is placed HERE.<br /><br />Here is the translation.<br />#Thanks to Zou, he helped me review this translation.<br />#There are some features about the compiler and VM are remained as original, because I am short at this areas. If you have any suggestions, please leave your comments of send a mail to my mailbox: tonny.xugmail.com<br /><br />TOTO.net     braket     <br />Just another WordPress weblog<br />Blog     Technical Articles     Photos     Resume     <br /><br />Java SE 6.0(代号?Mustang")是即将面世的下一版本Java。相比较J2SE 5.0，添加了许多重要的特性和增强功能，这些新特性和增强功能如下面的列表。<br /><br />所有的条目都按照涉及范围以及所属的组件分类。第一列表示了修改涉及的范围。<br /><br />    * JSR - 表示这是实现了某一项JSR（Java标准需求）的重大特性<br />    * API - 表示新添加的API<br />    * IMP - 表示没有增加新的API，只是作了一些类似性能增强的改进。<br /><br />请注意：这是个Beta里程碑，?Mustang?还在继续开发中。这些都是JSR270中的内容。JSR270本身并没有定义新的特性，但是它列举了一系列的其他JSR或者是正在进行评审中的需求。?Mustang?的最终发布版的目标是包含JSR270中所有的特性，但是不保证（有些已经商议通过的特性可能最终不会在?野马?版本中实现）。
          <br/>
          <span style="color:red;">
            <a href="http://yuhlster.javaeye.com/blog/25272#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 29 Sep 2006 08:09:46 +0800</pubDate>
        <link>http://yuhlster.javaeye.com/blog/25272</link>
        <guid>http://yuhlster.javaeye.com/blog/25272</guid>
      </item>
      <item>
        <title>ArrayList&lt;String&gt;.toArray()的问题</title>
        <author>青雉</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yuhlster.javaeye.com">青雉</a>&nbsp;
          链接：<a href="http://yuhlster.javaeye.com/blog/25227" style="color:red;">http://yuhlster.javaeye.com/blog/25227</a>&nbsp;
          发表时间: 2006年09月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          今天遇到个问题。<br />ArrayList&lt;String> list = new ArrayList&lt;String>();<br />		list.add("1");<br />		list.add("2");<br />String[] tt = list.toArray();<br />这个编译的时候会出问题。<br />String[] tt = (String[])list.toArray();<br />这个编译就过去了。但运行的时候就出异常了。<br />后来在网上找。<br />终于找到。<br />Java文档有一种推荐写法   <br />  String[]   tt=(String[])list.toarray(new String[0]);
          <br/>
          <span style="color:red;">
            <a href="http://yuhlster.javaeye.com/blog/25227#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 28 Sep 2006 15:28:30 +0800</pubDate>
        <link>http://yuhlster.javaeye.com/blog/25227</link>
        <guid>http://yuhlster.javaeye.com/blog/25227</guid>
      </item>
      <item>
        <title>Java1.5特性</title>
        <author>青雉</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yuhlster.javaeye.com">青雉</a>&nbsp;
          链接：<a href="http://yuhlster.javaeye.com/blog/25184" style="color:red;">http://yuhlster.javaeye.com/blog/25184</a>&nbsp;
          发表时间: 2006年09月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          今天早网上找了找java1.5的信特性。6.0的没找到。<br /> 泛型 <br /> 增强的for 循环 <br /> 自动装箱/拆箱 <br /> 类型安全的枚举 <br /> 静态导入 <br /> 元数据 <br />1. 自动装箱与拆箱 对应C#<br /> 例1.1<br />  Integer i = 10;<br />  int j = i;<br />  <br />2. 更优化的for循环 对应就C#---foreach循环<br /> 例2.1<br />  String[] names = {"BadBoy","GoodBoy","HappyGirl","sadGirl"};<br />  for(String option: names) {<br />   System.out.println(option);<br />  }<br /> 例2.2 加泛型 对应C++模板<br />  import java.util.*;<br />  <br />  ArrayList&lt;String> animals = new ArrayList&lt;String>();<br />  animals.add("Dog");<br />  animals.add("Cat");<br />  animals.add("Chick");<br />  animals.add("Cow");<br />  for(String option : animals) {<br />   System.out.println(option);<br />  }<br />  <br />3.参数可变的方法和printf<br /> 例3.1<br />  定义:<br />  public int sum(int... n) {  //传过来n为一个int型数组<br />   int tempSum;<br />   for(int option : n) {<br />    tempSum+=option;<br />   }<br />   /*<br />   for(int i = 0; i &lt; n.length; i++) {<br />    tempSum+=n[i];<br />   }<br />   */<br />   return tempSum;<br />  }<br />  调用1: sum(1);<br />  调用2: sum(1,2);<br />  调用3: sum(1,2,3,4);<br /> 例3.2 printf方法,  对应c语言的printf<br />  int x = 10;<br />  int y = 20;<br />  int sum = x + y;<br />  System.out.printf("%d + %d = %d",x,y,sum);<br />4. 枚举<br /> 例4.1<br />  public enum MyColors {<br />   red,<br />   black,<br />   blue,<br />   green,<br />   yellow<br />  }<br />  <br />  MyColors color = MyColors.red;<br />  for(MyColors option : color.values()) {<br />   System.out.println(option);<br />  }<br /><br />/**不能在switch语句里这样写case MyColors.red:<br /> *这样编译器不会让你通过*/<br />switch(color) {<br /> case red:<br />  System.out.println("best color is "+red);<br />  break;<br /> case black:<br />  System.out.println("NO " + black);<br />  break;<br /> default:<br />  System.out.println("What");<br />  break;<br />}<br /><br />5.静态引用<br /> 例5.1<br />  1.5版本以前的写法是：<br /> <br />  　　import java.lang.Math; //程序开头处<br />  <br />  　　...<br />  <br />  　　double x = Math.random(); <br />  1.5版本中可以这样写<br />   import static java.lang.Math.random; //程序开头处<br />   <br />   ...<br />  　　<br />   double x = random();
          <br/>
          <span style="color:red;">
            <a href="http://yuhlster.javaeye.com/blog/25184#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 28 Sep 2006 09:20:36 +0800</pubDate>
        <link>http://yuhlster.javaeye.com/blog/25184</link>
        <guid>http://yuhlster.javaeye.com/blog/25184</guid>
      </item>
      <item>
        <title>java.util包（二）</title>
        <author>青雉</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yuhlster.javaeye.com">青雉</a>&nbsp;
          链接：<a href="http://yuhlster.javaeye.com/blog/25108" style="color:red;">http://yuhlster.javaeye.com/blog/25108</a>&nbsp;
          发表时间: 2006年09月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          本章介绍Java的实用工具类库java.util包。在这个包中，Java提供了一些实用的方法和数据结构。例如，Java提供日期(Data)类、日历(Calendar)类来产生和获取日期及时间，提供随机数(Random)类产生各种类型的随机数，还提供了堆栈(Stack)、向量(Vector) 、位集合(Bitset)以及哈希表(Hashtable)等类来表示相应的数据结构。<br />　　图1.1给出了java.util包的基本层次结构图。下面我们将具体介绍其中几个重要的类。<br />　　　　　　　　　　　┌java.util.BitSet<br />　　　　　　　　　　　│java.util.Calendar<br />　　　　　　　　　　　│　　　　　　└java.util.GregorianCalendar<br />　　　　　　　　　　　│java.util.Date<br />　　　　　　　　　　　│java.util.Dictionary<br />　　　　　　　　　　　│　　　　　　└java.util.Hashtable<br />　　　　　　　　　　　│　　　　　　　　　　　　　└java.util.Properties<br />　　　　　　　　　　　│java.util.EventObject<br />　　　　　　　　　　　│java.util.ResourceBundle<br />　　　　　　　┌普通类┤　　　　　　├java.util.ListResourceBundle<br />　　　　　　　│　　　│　　　　　　└java.util.PropertyResourceBundle<br />　　　　　　　│　　　│java.util.Local<br />　　　　　　　│　　　│java.util.Observable<br />　　　　　　　│　　　│java.util.Random<br />　　　　　　　│　　　│java.util.StringTokenizer<br />　　　　　　　│　　　│java.util.Vector<br />　　　　　　　│　　　│　　　　　　└java.util.Stack<br />　　Java.util┤　　　└java.util.TimeZone<br />　　　　　　　│　　　　　　　　　　└java.util.SimpleTimeZone<br />　　　　　　　│　　　┌java.util.Enumeration<br />　　　　　　　├接　口┤java.util.EventListener<br />　　　　　　　│　　　└java.util.Observer<br />　　　　　　　│　　　┌java.util.EmptyStackException<br />　　　　　　　└异常类┤java.util.MissingResourceException<br />　　　　　　　　　　　│java.util.NoSuchElementException<br />　　　　　　　　　　　└java.util.TooManyListenersException<br />　　　　　　　图1.1 java.util包的基本层次结构<br /><br /><br />1.2 日期类Date<br /><br />　　Java在日期类中封装了有关日期和时间的信息，用户可以通过调用相应的方法来获取系统时间或设置日期和时间。Date类中有很多方法在JDK1.0公布后已经过时了，在8.3中我们将介绍JDK1.0中新加的用于替代Date的功能的其它类。<br />　　在日期类中共定义了六种构造函数。<br />　　(1)public Date()<br />　　创建的日期类对象的日期时间被设置成创建时刻相对应的日期时间。<br />　　例 Date today=new Date()；//today被设置成创建时刻相对应的日期时间。<br />　　(2)public Date (long date)<br />　　long 型的参数date可以通过调用Date类中的static方法parse(String s)来获得。<br />　　例 long l=Date.parse("Mon 6 Jan 1997 13:3:00");<br />　　　　Date day=new Date(l);<br />　　//day中时间为1997年 1月6号星期一，13:3:00。<br />　　(3)public Date(String s)<br />　　按字符串s产生一日期对象。s的格式与方法parse中字符串参数的模式相同。<br />　　例 Date day=new Date("Mon 6 Jan 1997 13:3:00");<br />　　//day 中时间为1997年1月6号星期一，13:3:00.<br />　　(4)public Date(int year,int month,int date)<br />　　(5)public Date(int year,int month,int date,int hrs,int min)<br />　　(6)public Date(int year,int month,int date,int hrs,int min,int sec)<br />　　按给定的参数创建一日期对象。<br />　　参数说明：<br />　　year的值为：需设定的年份-1900。例如需设定的年份是1997则year的值应为97，即1997-1900的结果。所以Date中可设定的年份最小为1900；<br />　　month的值域为0～11，0代表1月，11表代表12月；<br />　　date的值域在1～31之间；<br />　　hrs的值域在0～23之间。从午夜到次日凌晨1点间hrs=0，从中午到下午1点间hrs=12；<br />　　min和sec的值域在0～59之间。<br />　　例 Date day=new Date(11,3,4);<br />　　//day中的时间为：04-Apr-11 12:00:00 AM<br />另外，还可以给出不正确的参数。<br />　　例　设定时间为1910年2月30日，它将被解释成3月2日。<br />　　Date day=new Date(10,1,30,10,12,34);<br />　　System.out.println("Day's date is:"+day);<br />　　//打印结果为：Day's date is:Web Mar 02 10:13:34 GMT+08:00 1910<br />　　下面我们给出一些Date类中常用方法。<br />　　(1)public static long UTC(int year,int month,int date,int hrs. int min,int sec)<br />　　该方法将利用给定参数计算UTC值。UTC是一种计时体制，与GMT(格林威治时间)的计时体系略有差别。UTC计时体系是基于原子时钟的，而GTMT计时体系是基于天文学观测的。计算中使用的一般为GMT计时体系。<br />　　(2)public static long parse(String s)<br />　　该方法将字符串s转换成一个long型的日期。在介绍构造方法Date(long date)时曾使用过这个方法。<br />　　字符串s有一定的格式，一般为：<br />　　(星期 日 年 时间GMT+时区)<br />　　若不注明时区，则为本地时区。<br />　　(3)public void setMonth(int month)<br />　　(4)public int getMonth()<br />　　这两个方法分别为设定和获取月份值。<br />　　获取的月份的值域为0～11，0代表1月，11代表12月。<br />　　(5)public String toString()<br />　　(6)public String toLocalString()<br />　　(7)public String toGMTString()<br />　　将给定日期对象转换成不同格式的字符串。它们对应的具体的格式可参看例子8.1。<br />　　(8)public int getTimezoneOffset()<br />　　该方法用于获取日期对象的时区偏移量。<br />　　例8.1中对上面介绍的Date类中的基本方法进行了具体的应用，并打印了相应的结果。由于使用了一些过时的方法，所以编译时会有警告信息。另外，由于本例中的时间表示与平台有关，不同的JDK版本对此处理不完全相同，因此不同版本的JDK执行本例的结果可能有细微差异。<br />　　例1.1 DateApp.java<br />　　import java.lang.System;<br />　　import java.util.Date;<br />　　public class DateApp{<br />　　　public static void main(String args[]){<br />　　　　Date today=new Date();<br />　　　　//today中的日期被设成创建时刻的日期和时间，假设创建时刻为1997年3月<br />　　　　//23日17时51分54秒。<br />　　　　System.out.println("Today's date is "+today);<br />　　　　//返回一般的时间表示法，本例中结果为<br />　　　　//Today's date is Fri May 23 17:51:54 1997<br />　　　　System.out.println("Today's date(Internet GMT)is:"<br />　　　　　+today.toGMTString());<br />　　　　//返回结果为GMT时间表示法，本例中结果为<br />　　　　//Today's date(Internet GMT)is: 23 May 1997 09:51:54:GMT<br />　　　　System.out.println("Today's date(Locale) is:"<br />　　　　　+today.toLocaleString());<br />　　　　//返回结果为本地习惯的时间表示法，结果为<br />　　　　//Today's date(Locale)is:05/23/97 17:51:54<br />　　　　System.out.println("Today's year is: "+today.getYear());<br />　　　　System.out.println("Today's month is: "+(today.getMonth()+1));<br />　　　　System.out.println("Today's date is: "+today.getDate());<br />　　　　//调用Date类中方法，获取年月日的值。<br />　　　　//下面调用了不同的构造方法来创建Date类的对象。<br />　　　　Date day1=new Date(100,1,23,10,12,34);<br />　　　　System.out.println("Day1's date is: "+day1);<br />　　　　Date day2=new Date("Sat 12 Aug 1996 13:3:00");<br />　　　　System.out.println("Day2's date is: "+day2);<br />　　　　long l= Date.parse("Sat 5 Aug 1996 13:3:00 GMT+0800");<br />　　　　Date day3= new Date(l);<br />　　　　System.out.println("Day3's date(GMT)is: "+day3.toGMTString());<br />　　　　System.out.println("Day3's date(Locale)is: "<br />　　　　　+day3.toLocaleString());<br />　　　　System.out.println("Day3's time zone offset is:"<br />　　　　　+day3.getTimezoneOffset());<br />　　　}<br />　　}<br /><br />　　运行结果(JDK1.3版，与原文不同，原文是JDK1.0版)：<br />　　E:\java\tutorial\java01>java DateApp<br />　　Today's date is Thu Dec 27 17:58:16 CST 2001<br />　　Today's date(Internet GMT)is:27 Dec 2001 09:58:16 GMT<br />　　Today's date(Locale) is:2001-12-27 17:58:16<br />　　Today's year is: 101<br />　　Today's month is: 12<br />　　Today's date is: 27<br />　　Day1's date is: Wed Feb 23 10:12:34 CST 2000<br />　　Day2's date is: Fri Aug 12 13:03:00 CST 1996<br />　　Day3's date(GMT)is: 5 Aug 1996 05:03:00 GMT<br />　　Day3's date(Locale)is: 1996-8-5 13:03:00<br />　　Day3's time zone offset is:-480<br /><br />　　E:\java\tutorial\java01><br /><br />1.3 日历类Calendar<br /><br />　　在早期的JDK版本中，日期(Date)类附有两大功能：(1)允许用年、月、日、时、分、秒来解释日期：(2)允许对表示日期的字符串进行格式化和句法分析。在JDK1.1中提供了类Calendar来完成第一种功能，类DateFormat来完成第二项功能。dateFormat是java.text包中的一个类。与Date类有所不同的是，DateFormat类接受用各种语言和不同习惯表示的日期字符串。本节将介绍java.util包中的类Calendar及其它新增加的相关的类。<br />　　类Calendar是一个抽象类，它完成日期(Date)类和普通日期表示法(即用一组整型域如YEAR，MONTH，DAY，HOUR表示日期)之间的转换。<br />　　由于所使用的规则不同，不同的日历系统对同一个日期的解释有所不同。在JDK1.1中提供了Calendar类一个子类GregorianCalendar??它实现了世界上普遍使用的公历系统。当然用户也可以通过继承Calendar类，并增加所需规则，以实现不同的日历系统。<br />　　第GregorianCalendar继承了Calendar类。本节将在介绍类GregorianCalendar的同时顺带介绍Calendar类中的相关方法。<br />　　类GregorianCalendar提供了七种构造函数：<br />　　(1)public GregorianCalendar()<br />　　创建的对象中的相关值被设置成指定时区，缺省地点的当前时间，即程序运行时所处的时区、地点的当前时间。<br />　　(2)public GregorianCalendar(TimeZone zone)<br />　　创建的对象中的相关值被设置成指定时区zone，缺省地点的当前时间。<br />　　(3)public GregorianCalendar(Locale aLocale)<br />　　创建的对象中的相关值被设置成缺省时区，指定地点aLocale的当前时间。<br />　　(4)public GregorianCalendar(TimeZone zone,Local aLocale)<br />　　创建的对象中的相关值被设置成指定时区，指定地点的当前时间。<br />　　上面使用到的类TimeZone的性质如下：<br />　　TimeZone是java.util包中的一个类，其中封装了有关时区的信息。每一个时区对应一组ID。类TimeZone提供了一些方法完成时区与对应ID两者之间的转换。<br />　　(Ⅰ)已知某个特定的ID，可以调用方法<br />　　public static synchronized TimeZone getTimeZone(String ID)<br />来获取对应的时区对象。<br />　　例 太平洋时区的ID为PST，用下面的方法可获取对应于太平洋时区的时区对象：<br />　　TimeZone tz=TimeZone.getTimeZone("PST");<br />　　调用方法getDefault()可以获取主机所处时区的对象。<br />　　TimeZone tz=TimeZone.getDefault();<br />　　(Ⅱ)调用以下方法可以获取时区的ID<br />　　■public static synchronized String[] getavailableIDs(int rawOffset)<br />　　根据给定时区偏移值获取ID数组。同一时区的不同地区的ID可能不同，这是由于不同地区对是否实施夏时制意见不统一而造成的。<br />　　例String s[]=TimeZone.getAvailableIDs(-7*60*60*1000);<br />　　打印s，结果为s[0]=PNT，s[1]=MST<br />　　■public static synchronized String[] getAvailableIDs()<br />　　获取提供的所有支持的ID。<br />　　■public String getID()<br />　　获取特定时区对象的ID。<br />　　例 TimeZone tz=TimeZone.getDefault();<br />　　String s=tz.getID();<br />　　打印s，结果为s=CTT。<br />　　上面使用类的对象代表了一个特定的地理、政治或文化区域。Locale只是一种机制，它用来标识一类对象，Local本身并不包含此类对象。<br />　　要获取一个Locale的对象有两种方法：<br />　　(Ⅰ)调用Locale类的构造方法<br />　　Locale(String language,String country)<br />　　Locale(String language,String country,String variant)<br />　　参数说明：language??在ISO-639中定义的代码，由两个小写字母组成。<br />　　　　　　　country??在ISO-3166中定义的代码，由两个大写字母组成。<br />　　　　　　　variant??售货商以及特定浏览器的代码，例如使用WIN代表Windows。<br />　　(Ⅱ)调用Locale类中定义的常量<br />　　Local类提供了大量的常量供用户创建Locale对象。<br />　　例 Locale.CHINA<br />　　　　为中国创建一个Locale的对象。<br />　　类TimeZone和类Locale中的其它方法，读者可查阅API。<br />　　(5)public GregorianCalendar(int year,int month,int date)<br />　　(6)public GregorianCalendar(int year,int month,int date,int hour,int minute)<br />　　(7)public GregorianCalendar(int year,int month,int date,int hour,int minute,int second)<br />　　用给定的日期和时间创建一个GregorianCalendar的对象。<br />　　参数说明：<br />　　year-设定日历对象的变量YEAR；month-设定日历对象的变量MONTH；<br />　　date-设定日历对象的变量DATE；hour-设定日历对象的变量HOUR_OF_DAY；<br />　　minute-设定日历对象的变量MINUTE；second-设定日历对象的变量SECOND。<br />　　与Date类中不同的是year的值没有1900这个下限，而且year的值代表实际的年份。month的含义与Date类相同，0代表1月，11代表12月。<br />　　例 GregorianCalendar cal=new GregorianCalendar(1991,2,4)<br />　　cal的日期为1991年3月4号。<br />　　除了与Date中类似的方法外，Calendar类还提供了有关方法对日历进行滚动计算和数学计算。计算规则由给定的日历系统决定。进行日期计算时，有时会遇到信息不足或信息不实等特殊情况。Calendar采取了相应的方法解决这些问题。当信息不足时将采用缺省设置，在GregorianCalendar类中缺省设置一般为YEAR=1970,MONTH=JANUARY,DATE=1。<br />　　当信息不实时，Calendar将按下面的次序优先选择相应的Calendar的变量组合，并将其它有冲突的信息丢弃。<br />　　MONTH+DAY_OF_MONTH<br />　　MONTH+WEEK_OF_MONTH+DAY_OF_WEEK<br />　　MONTH+DAY_OF_WEEK_OF_MONTH+DAY_OF_WEEK<br />　　DAY_OF+YEAR<br />　　DAY_OF_WEEK_WEEK_OF_YEAR<br />　　HOUR_OF_DAY<br /><br />1.4 随机数类Random<br /><br />　　Java实用工具类库中的类java.util.Random提供了产生各种类型随机数的方法。它可以产生int、long、float、double以及Goussian等类型的随机数。这也是它与java.lang.Math中的方法Random()最大的不同之处，后者只产生double型的随机数。<br />　　类Random中的方法十分简单，它只有两个构造方法和六个普通方法。<br />　　构造方法：<br />　　(1)public Random()<br />　　(2)public Random(long seed)<br />　　Java产生随机数需要有一个基值seed，在第一种方法中基值缺省，则将系统时间作为seed。<br />　　普通方法：<br />　　(1)public synonronized void setSeed(long seed)<br />　　该方法是设定基值seed。<br />　　(2)public int nextInt()<br />　　该方法是产生一个整型随机数。<br />　　(3)public long nextLong()<br />　　该方法是产生一个long型随机数。<br />　　(4)public float nextFloat()<br />　　该方法是产生一个Float型随机数。<br />　　(5)public double nextDouble()<br />　　该方法是产生一个Double型随机数。<br />　　(6)public synchronized double nextGoussian()<br />　　该方法是产生一个double型的Goussian随机数。<br />　　例1.2 RandomApp.java。<br />　　//import java.lang.*;<br />　　import java.util.Random;<br /><br />　　public class RandomApp{<br />　　　public static void main(String args[]){<br />　　　　Random ran1=new Random();<br />　　　　Random ran2=new Random(12345);<br />　　　　//创建了两个类Random的对象。<br />　　　　System.out.println("The 1st set of random numbers:");<br />　　　　System.out.println("\t Integer:"+ran1.nextInt());<br />　　　　System.out.println("\t Long:"+ran1.nextLong());<br />　　　　System.out.println("\t Float:"+ran1.nextFloat());<br />　　　　System.out.println("\t Double:"+ran1.nextDouble());<br />　　　　System.out.println("\t Gaussian:"+ran1.nextGaussian());<br />　　　　//产生各种类型的随机数<br />　　　　System.out.print("The 2nd set of random numbers:");<br />　　　　for(int i=0;i&lt;5;i++){<br />　　　　　System.out.println(ran2.nextInt()+" ");<br />　　　　　if(i==2) System.out.println();<br />　　　　　//产生同种类型的不同的随机数。<br />　　　　　System.out.println();//原文如此<br />　　　　}<br />　　　}<br />　　}<br /><br />　　运行结果：<br />　　E:\java01>java RandomApp<br />　　The 1st set of random numbers:<br />　　　　Integer:-173899656<br />　　　　Long:8056223819738127077<br />　　　　Float:0.6293638<br />　　　　Double:0.7888394520265607<br />　　　　Gaussian:0.5015701094568733<br />　　The 2nd set of random numbers:1553932502<br />　　-2090749135<br />　　-287790814<br />　　-355989640<br />　　-716867186<br />　　E:\java01><br /><br />1.5 向量类Vector<br /><br />　　Java.util.Vector提供了向量(Vector)类以实现类似动态数组的功能。在Java语言中。正如在一开始就提到过，是没有指针概念的，但如果能正确灵活地使用指针又确实可以大大提高程序的质量，比如在C、C++中所谓“动态数组”一般都由指针来实现。为了弥补这点缺陷，Java提供了丰富的类库来方便编程者使用，Vector类便是其中之一。事实上，灵活使用数组也可完成向量类的功能，但向量类中提供的大量方法大大方便了用户的使用。<br />　　创建了一个向量类的对象后，可以往其中随意地插入不同的类的对象，既不需顾及类型也不需预先选定向量的容量，并可方便地进行查找。对于预先不知或不愿预先定义数组大小，并需频繁进行查找、插入和删除工作的情况，可以考虑使用向量类。<br />　　向量类提供了三种构造方法：<br />　　public vector()<br />　　public vector(int initialcapacity,int capacityIncrement)<br />　　public vector(int initialcapacity)<br />　　使用第一种方法，系统会自动对向量对象进行管理。若使用后两种方法，则系统将根据参数initialcapacity设定向量对象的容量(即向量对象可存储数据的大小)，当真正存放的数据个数超过容量时，系统会扩充向量对象的存储容量。参数capacityIncrement给定了每次扩充的扩充值。当capacityIncrement为0时，则每次扩充一倍。利用这个功能可以优化存储。<br />　　在Vector类中提供了各种方法方便用户使用：<br />　　■插入功能<br />　　(1)public final synchronized void addElement(Object obj)<br />　　将obj插入向量的尾部。obj可以是任何类的对象。对同一个向量对象，可在其中插入不同类的对象。但插入的应是对象而不是数值，所以插入数值时要注意将数值转换成相应的对象。<br />　　例 要插入一个整数1时，不要直接调用v1.addElement(1)，正确的方法为：<br />　　Vector v1=new Vector();<br />　　Integer integer1=new Integer(1);<br />　　v1.addElement(integer1);<br />　　(2)public final synchronized void setElementAt(object obj,int index)<br />　　将index处的对象设成obj，原来的对象将被覆盖。<br />　　(3)public final synchronized void insertElementAt(Object obj,int index)<br />　　在index指定的位置插入obj，原来对象以及此后的对象依次往后顺延。<br />　　■删除功能<br />　　(1)public final synchronized void removeElement(Object obj)<br />　　从向量中删除obj。若有多个存在，则从向量头开始试，删除找到的第一个与obj相同的向量成员。<br />　　(2)public final synchronized void removeAllElement()<br />　　删除向量中所有的对象。<br />　　(3)public final synchronized void removeElementlAt(int index)<br />　　删除index所指的地方的对象。<br />　　■查询搜索功能<br />　　(1)public final int indexOf(Object obj)<br />　　从向量头开始搜索obj ,返回所遇到的第一个obj对应的下标，若不存在此obj，返回-1。<br />　　(2)public final synchronized int indexOf(Object obj,int index)<br />　　从index所表示的下标处开始搜索obj。<br />　　(3)public final int lastIndexOf(Object obj)<br />　　从向量尾部开始逆向搜索obj。<br />　　(4)public final synchronized int lastIndexOf(Object obj,int index)<br />　　从index所表示的下标处由尾至头逆向搜索obj。<br />　　(5)public final synchronized Object firstElement()<br />　　获取向量对象中的首个obj。<br />　　(6)public final synchronized Object lastelement()<br />　　获取向量对象中的最后一个obj。<br />　　了解了向量的最基本的方法后，我们来看一下例8.3VectorApp.java。<br />　　例1.3 VectorApp.java。<br />　　import java.util.Vector;<br />　　import java.lang.*;//这一句不应该要，但原文如此<br />　　import java.util.Enumeration;<br />　　public class VectorApp{<br />　　　public static void main(String[] args){<br />　　　　Vector v1=new Vector();<br />　　　　Integer integer1=new Integer(1);<br />　　　　v1.addElement("one");<br />　　　　//加入的为字符串对象<br />　　　　v1.addElement(integer1);<br />　　　　v1.addElement(integer1);<br />　　　　//加入的为Integer的对象<br />　　　　v1.addElement("two");<br />　　　　v1.addElement(new Integer(2));<br />　　　　v1.addElement(integer1);<br />　　　　v1.addElement(integer1);<br />　　　　System.out.println("The vector v1 is:\n\t"+v1);<br />　　　　//将v1转换成字符串并打印<br />　　　　v1.insertElementAt("three",2);<br />　　　　v1.insertElementAt(new Float(3.9),3);<br />　　　　System.out.println("The vector v1(used method insertElementAt()) is:\n\t "+v1);<br />　　　　//往指定位置插入新的对象，指定位置后的对象依次往后顺延<br />　　　　v1.setElementAt("four",2);<br />　　　　System.out.println("The vector v1(used method setElementAt()) is:\n\t "+v1);<br />　　　　//将指定位置的对象设置为新的对象<br />　　　　v1.removeElement(integer1);<br />　　　　//从向量对象v1中删除对象integer1由于存在多个integer1所以从头开始<br />　　　　//找，删除找到的第一个integer1<br />　　　　Enumeration enum=v1.elements();<br />　　　　System.out.print("The vector v1(used method removeElement())is:");<br />　　　　while(enum.hasMoreElements())<br />　　　　System.out.print(enum.nextElement()+" ");<br />　　　　System.out.println();<br />　　　　//使用枚举类(Enumeration)的方法来获取向量对象的每个元素<br />　　　　System.out.println("The position of object 1(top-to-bottom):"<br />　　　　　+ v1.indexOf(integer1));<br />　　　　System.out.println("The position of object 1(tottom-to-top):"<br />　　　　　+v1.lastIndexOf(integer1));<br />　　　　//按不同的方向查找对象integer1所处的位置<br />　　　　v1.setSize(4);<br />　　　　System.out.println("The new vector(resized the vector)is:"+v1);<br />　　　　//重新设置v1的大小，多余的元素被行弃<br />　　　}<br />　　}<br />　　运行结果：<br />　　E:\java01>java VectorApp<br />　　The vector v1 is:<br />　　　　　[one, 1, 1, two, 2, 1, 1]<br />　　The vector v1(used method insertElementAt()) is:<br />　　　　　[one, 1, three, 3.9, 1, two, 2, 1, 1]<br />　　The vector v1(used method setElementAt()) is:<br />　　　　　[one, 1, four, 3.9, 1, two, 2, 1, 1]<br />　　The vector v1(used method removeElement())is:one four 3.9 1 two 2 1 1<br />　　The position of object 1(top-to-bottom):3<br />　　The position of object 1(tottom-to-top):7<br />　　The new vector(resized the vector)is:[one, four, 3.9, 1]<br />　　E:\java01><br />　　从例1.3运行的结果中可以清楚地了解上面各种方法的作用，另外还有几点需解释。<br />　　(1)类Vector定义了方法<br />　　public final int size()<br />　　此方法用于获取向量元素的个数。它的返回值是向是中实际存在的元素个数，而非向量容量。可以调用方法capactly()来获取容量值。<br />　　方法：<br />　　public final synchronized void setsize(int newsize)<br />　　此方法用来定义向量大小。若向量对象现有成员个数已超过了newsize的值，则超过部分的多余元素会丢失。<br />　　(2)程序中定义了Enumeration类的一个对象<br />　　Enumeration是java.util中的一个接口类，在Enumeration中封装了有关枚举数据集合的方法。<br />　　在Enumeration中提供了方法hawMoreElement()来判断集合中是束还有其它元素和方法nextElement()来获取下一个元素。利用这两个方法可以依次获得集合中元素。<br />　　Vector中提供方法：<br />　　public final synchronized Enumeration elements()<br />　　此方法将向量对象对应到一个枚举类型。java.util包中的其它类中也大都有这类方法，以便于用户获取对应的枚举类型。<br /><br />1.6 栈类Stack<br /><br />　　Stack类是Vector类的子类。它向用户提供了堆栈这种高级的数据结构。栈的基本特性就是先进后出。即先放入栈中的元素将后被推出。Stack类中提供了相应方法完成栈的有关操作。<br />　　基本方法：<br />　　public Object push(Object Hem)<br />　　将Hem压入栈中，Hem可以是任何类的对象。<br />　　public Object pop()<br />　　弹出一个对象。<br />　　public Object peek()<br />　　返回栈顶元素，但不弹出此元素。<br />　　public int search(Object obj)<br />　　搜索对象obj,返回它所处的位置。<br />　　public boolean empty()<br />　　判别栈是否为空。<br />　　例1.4 StackApp.java使用了上面的各种方法。<br />　　例1.4 StackApp.java。<br />　　import java.lang.*;<br />　　import java.util.*;<br />　　public class StackApp{<br />　　　public static void main(String args[]){<br />　　　　Stack sta=new Stack();<br />　　　　sta.push("Apple");<br />　　　　sta.push("banana");<br />　　　　sta.push("Cherry");<br />　　　　//压入的为字符串对象<br />　　　　sta.push(new Integer(2));<br />　　　　//压入的为Integer的对象，值为2<br />　　　　sta.push(new Float(3.5));<br />　　　　//压入的为Float的对象，值为3.5<br />　　　　System.out.println("The stack is,"+sta);<br />　　　　//对应栈sta<br />　　　　System.out.println("The top of stack is:"+sta.peek());<br />　　　　//对应栈顶元素，但不将此元素弹出<br />　　　　System.out.println("The position of object Cherry is:"<br />　　　　+sta.search("cherry"));<br />　　　　//打印对象Cherry所处的位置<br />　　　　System.out.print("Pop the element of the stack:");<br />　　　　while(!sta.empty())<br />　　　　System.out.print(sta.pop()+" ");<br />　　　　System.out.println();<br />　　　　//将栈中的元素依次弹出并打印。与第一次打印的sta的结果比较，可看出栈<br />　　　　//先进后出的特点<br />　　　}<br />　　}<br />　　运行结果(略)<br /><br /><br />1.7 哈希表类Hashtable<br /><br />　　哈希表是一种重要的存储方式，也是一种常见的检索方法。其基本思想是将关系码的值作为自变量，通过一定的函数关系计算出对应的函数值，把这个数值解释为结点的存储地址，将结点存入计算得到存储地址所对应的存储单元。检索时采用检索关键码的方法。现在哈希表有一套完整的算法来进行插入、删除和解决冲突。在Java中哈希表用于存储对象，实现快速检索。<br />　　Java.util.Hashtable提供了种方法让用户使用哈希表，而不需要考虑其哈希表真正如何工作。<br />　　哈希表类中提供了三种构造方法，分别是：<br />　　public Hashtable()<br />　　public Hashtable(int initialcapacity)<br />　　public Hashtable(int initialCapacity,float loadFactor)<br />　　参数initialCapacity是Hashtable的初始容量，它的值应大于0。loadFactor又称装载因子，是一个0.0到0.1之间的float型的浮点数。它是一个百分比，表明了哈希表何时需要扩充，例如，有一哈希表，容量为100，而装载因子为0.9，那么当哈希表90%的容量已被使用时，此哈希表会自动扩充成一个更大的哈希表。如果用户不赋这些参数，系统会自动进行处理，而不需要用户操心。<br />　　Hashtable提供了基本的插入、检索等方法。<br />　　■插入<br />　　public synchronized void put(Object key,Object value)<br />给对象value设定一关键字key,并将其加到Hashtable中。若此关键字已经存在，则将此关键字对应的旧对象更新为新的对象Value。这表明在哈希表中相同的关键字不可能对应不同的对象(从哈希表的基本思想来看，这也是显而易见的)。<br />　　■检索<br />　　public synchronized Object get(Object key)<br />　　根据给定关键字key获取相对应的对象。<br />　　public synchronized boolean containsKey(Object key)<br />　　判断哈希表中是否包含关键字key。<br />　　public synchronized boolean contains(Object value)<br />　　判断value是否是哈希表中的一个元素。<br />　　■删除<br />　　public synchronized object remove(object key)<br />　　从哈希表中删除关键字key所对应的对象。<br />　　public synchronized void clear()<br />　　清除哈希表<br />　　另外，Hashtalbe还提供方法获取相对应的枚举集合：<br />　　public synchronized Enumeration keys()<br />　　返回关键字对应的枚举对象。<br />　　public synchronized Enumeration elements()<br />　　返回元素对应的枚举对象。<br />　　例1.5 Hashtable.java给出了使用Hashtable的例子。<br />　　例1.5 Hashtalbe.java。<br />　　//import java.lang.*;<br />　　import java.util.Hashtable;<br />　　import java.util.Enumeration;<br />　　public class HashApp{<br />　　　public static void main(String args[]){<br />　　　　Hashtable hash=new Hashtable(2,(float)0.8);<br />　　　　//创建了一个哈希表的对象hash，初始容量为2，装载因子为0.8<br /><br />　　　　hash.put("Jiangsu","Nanjing");<br />　　　　//将字符串对象“Jiangsu”给定一关键字“Nanjing”,并将它加入hash<br />　　　　hash.put("Beijing","Beijing");<br />　　　　hash.put("Zhejiang","Hangzhou");<br /><br />　　　　System.out.println("The hashtable hash1 is: "+hash);<br />　　　　System.out.println("The size of this hash table is "+hash.size());<br />　　　　//打印hash的内容和大小<br /><br />　　　　Enumeration enum1=hash.elements();<br />　　　　System.out.print("The element of hash is: ");<br />　　　　while(enum1.hasMoreElements())<br />　　　　　System.out.print(enum1.nextElement()+" ");<br />　　　　System.out.println();<br />　　　　//依次打印hash中的内容<br />　　　　if(hash.containsKey("Jiangsu"))<br />　　　　　System.out.println("The capatial of Jiangsu is "+hash.get("Jiangsu"));<br />　　　　hash.remove("Beijing");<br />　　　　//删除关键字Beijing对应对象<br />　　　　System.out.println("The hashtable hash2 is: "+hash);<br />　　　　System.out.println("The size of this hash table is "+hash.size());<br />　　　}<br />　　}<br /><br />　　运行结果：<br />　　The hashtable hash1 is: {Beijing=Beijing, Zhejiang=Hangzhou, Jiangsu=Nanjing}<br />　　The size of this hash table is 3<br />　　The element of hash is: Beijing Hangzhou Nanjing<br />　　The capatial of Jiangsu is Nanjing<br />　　The hashtable hash2 is: {Zhejiang=Hangzhou, Jiangsu=Nanjing}<br />　　The size of this hash table is 2<br /><br />　　Hashtable是Dictionary(字典)类的子类。在字典类中就把关键字对应到数据值。字典类是一个抽象类。在java.util中还有一个类Properties，它是Hashtable的子类。用它可以进行与对象属性相关的操作。<br /><br />1.8 位集合类BitSet<br /><br />　　位集合类中封装了有关一组二进制数据的操作。<br />　　我们先来看一下例8.6 BitSetApp.java。<br />　　例8.6 BitSetApp.java<br />　　//import java.lang.*;<br />　　import java.util.BitSet;<br />　　public class BitSetApp{<br />　　　private static int n=5;<br />　　　public static void main(String[] args){<br />　　　　BitSet set1=new BitSet(n);<br />　　　　for(int i=0;i&lt;n;i++) set1.set(i);<br />　　　　//将set1的各位赋1，即各位均为true<br />　　　　BitSet set2= new BitSet();<br />　　　　set2=(BitSet)set1.clone();<br />　　　　//set2为set1的拷贝<br />　　　　set1.clear(0);<br />　　　　set2.clear(2);<br />　　　　//将set1的第0位set2的第2位清零<br />　　　　System.out.println("The set1 is: "+set1);<br />　　　　//直接将set1转换成字符串输出，输出的内容是set1中值true所处的位置<br />　　　　//打印结果为The set1 is:{1,2,3,4}<br />　　　　System.out.println("The hash code of set2 is: "+set2.hashCode());<br />　　　　//打印set2的hashCode<br />　　　　printbit("set1",set1);<br />　　　　printbit("set2",set2);<br />　　　　//调用打印程序printbit(),打印对象中的每一个元素<br />　　　　//打印set1的结果为The bit set1 is: false true true true true<br />　　　　set1.and(set2);<br />　　　　printbit("set1 and set2",set1);<br />　　　　//完成set1 and set2,并打印结果<br />　　　　set1.or(set2);<br />　　　　printbit("set1 or set2",set1);<br />　　　　//完成set1 or set2,并打印结果<br />　　　　set1.xor(set2);<br />　　　　printbit("set1 xor set2",set1);<br />　　　　//完成set1 xor set2,并打印结果<br />　　　}<br />　　　//打印BitSet对象中的内容<br />　　　public static void printbit(String name,BitSet set){<br />　　　　System.out.print("The bit "+name+" is: ");<br />　　　　for(int i=0;i&lt;n;i++)<br />　　　　　System.out.print(set.get(i)+" ");<br />　　　　System.out.println();<br />　　　}<br />　　}<br /><br />　　运行结果：<br />　　The set1 is: {1, 2, 3, 4}<br />　　The hash code of set2 is: 1225<br />　　The bit set1 is: false true true true true<br />　　The bit set2 is: true true false true true<br />　　The bit set1 and set2 is: false true false true true<br />　　The bit set1 or set2 is: true true false true true<br />　　The bit set1 xor set2 is: false false false false false<br /><br />　　程序中使用了BitSet类提供的两种构造方法：<br />　　　　public BitSet();<br />　　　　public BitSet(int n);<br />　　参数n代表所创建的BitSet类的对象的大小。BitSet类的对象的大小在必要时会由系统自动扩充。<br />　　其它方法：<br />　　public void set(int n)<br />　　将BitSet对象的第n位设置成1。<br />　　public void clear(int n)<br />　　将BitSet对象的第n位清零。<br />　　public boolean get(int n)<br />　　读取位集合对象的第n位的值，它获取的是一个布尔值。当第n位为1时，返回true；第n位为0时，返回false。<br />　　另外，如在程序中所示，当把一BitSet类的对象转换成字符串输出时，输出的内容是此对象中true所处的位置。<br />　　在BitSet中提供了一组位操作，分别是：<br />　　public void and(BitSet set)<br />　　public void or(BitSet set)<br />　　public void xor(BitSet set)<br />利用它们可以完成两个位集合之间的与、或、异或操作。<br />　　BitSet类中有一方法public int size()来取得位集合的大小，它的返回值与初始化时设定的位集合大小n不一样，一般为64。<br /><br />小结<br /><br />　　本章我们介绍了Java的实用工具类库java.util中一些常用的类。java.util包中还有其它一些类。它们的具体用法用户可以自行查阅API。
          <br/>
          <span style="color:red;">
            <a href="http://yuhlster.javaeye.com/blog/25108#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 27 Sep 2006 08:22:29 +0800</pubDate>
        <link>http://yuhlster.javaeye.com/blog/25108</link>
        <guid>http://yuhlster.javaeye.com/blog/25108</guid>
      </item>
      <item>
        <title>java.util包（一）</title>
        <author>青雉</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yuhlster.javaeye.com">青雉</a>&nbsp;
          链接：<a href="http://yuhlster.javaeye.com/blog/25107" style="color:red;">http://yuhlster.javaeye.com/blog/25107</a>&nbsp;
          发表时间: 2006年09月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          ArrayList是List接口的一个可变长数组实现。实现了所有List接口的操作，并允许存储null值。除了没有进行同步，ArrayList基本等同于Vector。在Vector中几乎对所有的方法都进行了同步，但ArrayList仅对writeObject和readObject进行了同步，其它比如add(Object)、remove(int)等都没有同步。<br /><br />1.存储<br />ArrayList使用一个Object的数组存储元素。<br />private transient Object elementData[];<br />ArrayList实现了java.io.Serializable接口，这儿的transient标示这个属性不需要自动序列化。下面会在writeObject()方法中详细讲解为什么要这样作。<br /><br />2.add和remove<br /><br /><br />    public boolean add(Object o) { <br />    ensureCapacity(size + 1);  // Increments modCount!! <br />    elementData[size++] = o; <br />    return true; <br />    } <br /><br />注意这儿的ensureCapacity()方法，它的作用是保证elementData数组的长度可以容纳一个新元素。在“自动变长机制”中将详细讲解。<br /><br />    public Object remove(int index) { <br />    RangeCheck(index); <br />    modCount++; <br />    Object oldValue = elementData[index]; <br />    int numMoved = size - index - 1; <br />    if (numMoved > 0) <br />        System.arraycopy(elementData, index+1, elementData, index, <br />                 numMoved); <br />    elementData[--size] = null; // Let gc do its work <br />    return oldValue; <br />    } <br /><br />RangeCheck()的作用是进行边界检查。由于ArrayList采用一个对象数组存储元素，所以在删除一个元素时需要把后面的元素前移。删除一个元素时只是把该元素在elementData数组中的引用置为null，具体的对象的销毁由垃圾收集器负责。<br />modCount的作用将在下面的“iterator()中的同步”中说明。<br />注：在前移时使用了System提供的一个实用方法：arraycopy()，在本例中可以看出System.arraycopy()方法可以对同一个数组进行操作，这个方法是一个native方法，如果对同一个数组进行操作时，会首先把从源部分拷贝到一个临时数组，在把临时数组的元素拷贝到目标位置。<br /><br />3.自动变长机制<br />在实例化一个ArrayList时，你可以指定一个初始容量。这个容量就是elementData数组的初始长度。如果你使用：<br /><br />    ArrayList list = new ArrayList(); <br /><br />则使用缺省的容量：10。<br /><br />    public ArrayList() { <br />    this(10); <br />    } <br /><br />ArrayList提供了四种add()方法，<br /><br />public boolean add(Object o)<br /><br />public void add(int index, Object element)<br /><br />public boolean addAll(Collection c)<br /><br />public boolean addAll(int index, Collection c)<br /><br />在每一种add()方法中，都首先调用了一个ensureCapacity(int miniCapacity)方法，这个方法保证elementData数组的长度不小于miniCapacity。ArrayList的自动变长机制就是在这个方法中实现的。<br /><br />    public void ensureCapacity(int minCapacity) { <br />    modCount++; <br />    int oldCapacity = elementData.length; <br />    if (minCapacity > oldCapacity) { <br />        Object oldData[] = elementData; <br />        int newCapacity = (oldCapacity * 3)/2 + 1; <br />            if (newCapacity &lt; minCapacity) <br />        newCapacity = minCapacity; <br />        elementData = new Object[newCapacity]; <br />        System.arraycopy(oldData, 0, elementData, 0, size); <br />    } <br />    } <br /><br />从这个方法实现中可以看出ArrayList每次扩容，都扩大到原来大小的1.5倍。<br />每种add()方法的实现都大同小异，下面给出add(Object)方法的实现：<br /><br />    public boolean add(Object o) { <br />    ensureCapacity(size + 1);  // Increments modCount!! <br />    elementData[size++] = o; <br />    return true; <br />    } <br /><br /><br />4.iterator()中的同步<br />在父类AbstractList中定义了一个int型的属性：modCount，记录了ArrayList结构性变化的次数。<br /><br />    protected transient int modCount = 0; <br /><br />在ArrayList的所有涉及结构变化的方法中都增加modCount的值，包括：add()、remove()、addAll()、removeRange()及clear()方法。这些方法每调用一次，modCount的值就加1。<br />注：add()及addAll()方法的modCount的值是在其中调用的ensureCapacity()方法中增加的。<br /><br />AbstractList中的iterator()方法（ArrayList直接继承了这个方法）使用了一个私有内部成员类Itr，生成一个Itr对象（Iterator接口）返回：<br /><br />    public Iterator iterator() { <br />    return new Itr(); <br />    } <br /><br />Itr实现了Iterator()接口，其中也定义了一个int型的属性：expectedModCount，这个属性在Itr类初始化时被赋予ArrayList对象的modCount属性的值。<br /><br />    int expectedModCount = modCount; <br /><br />注：内部成员类Itr也是ArrayList类的一个成员，它可以访问所有的AbstractList的属性和方法。理解了这一点，Itr类的实现就容易理解了。<br /><br />在Itr.hasNext()方法中：<br /><br />    public boolean hasNext() { <br />        return cursor != size(); <br />    } <br /><br />调用了AbstractList的size()方法，比较当前光标位置是否越界。<br /><br />在Itr.next()方法中，Itr也调用了定义在AbstractList中的get(int)方法，返回当前光标处的元素：<br /><br />    public Object next() { <br />        try { <br />        Object next = get(cursor); <br />        checkForComodification(); <br />        lastRet = cursor++; <br />        return next; <br />        } catch(IndexOutOfBoundsException e) { <br />        checkForComodification(); <br />        throw new NoSuchElementException(); <br />        } <br />    } <br /><br />注意，在next()方法中调用了checkForComodification()方法，进行对修改的同步检查：<br /><br />    final void checkForComodification() { <br />        if (modCount != expectedModCount) <br />        throw new ConcurrentModificationException(); <br />    } <br /><br />现在对modCount和expectedModCount的作用应该非常清楚了。在对一个集合对象进行跌代操作的同时，并不限制对集合对象的元素进行操作，这些操作包括一些可能引起跌代错误的add()或remove()等危险操作。在AbstractList中，使用了一个简单的机制来规避这些风险。这就是modCount和expectedModCount的作用所在。<br /><br />5.序列化支持<br />ArrayList实现了java.io.Serializable接口，所以ArrayList对象可以序列化到持久存储介质中。ArrayList的主要属性定义如下：<br /><br />private static final long serialVersionUID = 8683452581122892189L;<br /><br />private transient Object elementData[];<br /><br />private int size;<br /><br />可以看出serialVersionUID和size都将自动序列化到介质中，但elementData数组对象却定义为transient了。也就是说ArrayList中的所有这些元素都不会自动系列化到介质中。为什么要这样实现？因为elementData数组中存储的“元素”其实仅是对这些元素的一个引用，并不是真正的对象，序列化一个对象的引用是毫无意义的，因为序列化是为了反序列化，当你反序列化时，这些对象的引用已经不可能指向原来的对象了。所以在这儿需要手工的对ArrayList的元素进行序列化操作。这就是writeObject()的作用。<br /><br />    private synchronized void writeObject(java.io.ObjectOutputStream s) <br />        throws java.io.IOException{ <br />    // Write out element count, and any hidden stuff <br />    s.defaultWriteObject(); <br />   // Write out array length <br />    s.writeInt(elementData.length); <br />    // Write out all elements in the proper order. <br />    for (int i=0; i&lt;size; i++) <br />            s.writeObject(elementData[i]); <br />    } <br /><br />这样元素数组elementData中的所以元素对象就可以正确地序列化到存储介质了。<br />对应的readObject()也按照writeObject()方法的顺序从输入流中读取：<br /><br />    private synchronized void readObject(java.io.ObjectInputStream s) <br />        throws java.io.IOException, ClassNotFoundException { <br />    // Read in size, and any hidden stuff <br />    s.defaultReadObject(); <br />    // Read in array length and allocate array <br />    int arrayLength = s.readInt(); <br />    elementData = new Object[arrayLength]; <br />    // Read in all elements in the proper order. <br />    for (int i=0; i&lt;size; i++) <br />            elementData[i] = s.readObject(); <br />    }
          <br/>
          <span style="color:red;">
            <a href="http://yuhlster.javaeye.com/blog/25107#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 27 Sep 2006 08:21:22 +0800</pubDate>
        <link>http://yuhlster.javaeye.com/blog/25107</link>
        <guid>http://yuhlster.javaeye.com/blog/25107</guid>
      </item>
      <item>
        <title>禁止ctrl+n和 禁止ctrl+r和 禁止shift+f10 禁止鼠标右键or左右键 和禁止f5 的JS代码</title>
        <author>青雉</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yuhlster.javaeye.com">青雉</a>&nbsp;
          链接：<a href="http://yuhlster.javaeye.com/blog/24600" style="color:red;">http://yuhlster.javaeye.com/blog/24600</a>&nbsp;
          发表时间: 2006年09月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          禁止ctrl+n和 禁止ctrl+r和 禁止shift+f10 禁止鼠标右键or左右键 和禁止f5 的JS代码<br /><br />&lt;script><br />//禁止ctrl+n和 禁止ctrl+r和 禁止shift+f10 禁止鼠标右键or左右键 和禁止f5<br />var oLastBtn=0,bIsMenu=false <br />if (window.Event)<br />{<br />document.captureEvents(Event.MOUSEUP); <br />}<br /><br />function nocontextmenu()<br />{ <br />event.cancelBubble=true;<br />event.returnValue=false; <br />return false; <br />}<br /><br />function norightclick(e) <br /><br />{ <br />if(window.Event) <br />{ <br />if (e.which !=1)<br />{<br />return false; <br />}<br />} <br />else <br />if(event.button!=1) <br />{ <br />event.cancelBubble=true;<br />event.returnValue=false; <br />return false; <br />} <br />}<br /><br />document.oncontextmenu=nocontextmenu; <br />document.onmousedown=norightclick; <br /><br />function onKeyDown()<br />{<br />if ((event.altKey)||((event.keyCode==8)&&(event.srcElement.type!="text"&&event.srcElement.type!="textarea"&&event.srcElement.type!="password"))||((event.ctrlKey)&&((event.keyCode==78)||(event.keyCode==82)))||(event.keyCode==116))<br />{<br />event.keyCode=0;<br />event.returnValue=false;<br />}<br />}<br />&lt;/script><br />&lt;body onkeydown="onKeyDown()">
          <br/>
          <span style="color:red;">
            <a href="http://yuhlster.javaeye.com/blog/24600#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 19 Sep 2006 09:55:49 +0800</pubDate>
        <link>http://yuhlster.javaeye.com/blog/24600</link>
        <guid>http://yuhlster.javaeye.com/blog/24600</guid>
      </item>
      <item>
        <title>Ajax</title>
        <author>青雉</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yuhlster.javaeye.com">青雉</a>&nbsp;
          链接：<a href="http://yuhlster.javaeye.com/blog/24590" style="color:red;">http://yuhlster.javaeye.com/blog/24590</a>&nbsp;
          发表时间: 2006年09月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          AJAX全称为“Asynchronous JavaScript and XML”（异步JavaScript和XML），是一种创建交互式网页应用的网页开发技术。它使用： <br /><br />* 使用XHTML+CSS来表示信息； <br />* 使用JavaScript操作DOM（Document Object Model）进行动态显示及交互； <br />* 使用 XML 和 XSLT 进行数据交换及相关操作； <br />* 使用 XMLHttpRequest对象与Web服务器进行异步数据交换； <br />* 使用 JavaScript 将所有的东西绑定在一起。
          <br/>
          <span style="color:red;">
            <a href="http://yuhlster.javaeye.com/blog/24590#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 19 Sep 2006 08:24:40 +0800</pubDate>
        <link>http://yuhlster.javaeye.com/blog/24590</link>
        <guid>http://yuhlster.javaeye.com/blog/24590</guid>
      </item>
  </channel>
</rss>