The NoteBook of EricKong

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

#

     摘要: 在servlet中默认情况下,无论你是get还是post 提交过来 都会经过service()方法来处理,然后转向到doGet或是doPost方法,可以看HttpServlet 类的service方法:         原代码:  [c-sharp] view plaincopyprote...  阅读全文
posted @ 2014-01-06 14:54 Eric_jiang 阅读(259) | 评论 (0)编辑 收藏

     摘要:  之前对java中的数组一直是一知半解,特别是数组中的长度问题。今天对这个问题也算是小有理解,算是对java数组的有了更进一步的了解吧。不说了,先来例子再说: [java] view plaincopypackage com.test;    public class Test {&nbs...  阅读全文
posted @ 2014-01-06 11:40 Eric_jiang 阅读(207) | 评论 (0)编辑 收藏

       java里有个很重要的特色是Exception ,也就是说答应程序产生例外状况。而在学Java 的时候,我们也只知道Exception 的写法,却未必真能了解不同种类的Exception 的区别。
  首先,您应该知道的是Java 提供了两种Exception 的模式,一种是执行的时候所产生的Exception (Runtime Exception),另外一种则是受控制的Exception (Checked Exception)。
  所有的Checked Exception 均从java.lang.Exception 继续而来,而Runtime Exception 则继续java.lang.RuntimeException 或java.lang.Error (实际上java.lang.RuntimeException 的上一层也是java.lang.Exception)。
  当我们撰写程序的时候,我们很可能会对选择某种形式的Exception 感到困扰,到底我应该选择Runtime Exception 还是Checked Exception ?
  其实,在运作上,我们可以通过Class 的Method 如何产生某个Exception以及某个程序如何处理这个被产生来的Exception 来了解它们之间的差异。
首先我们先建立一个Exception
public class CException extends Exception
{
public CException() {}
public CException(String message)
{
super(message);
}
}
然后我们撰写一个可能产生 CException 的 Class
public class testException
{
public void method1() throws CException
{
throw new CException("Test Exception");
}
public void method2(String msg)
{
if(msg == null)
{
throw new NullPointerException("Message is null");
}
}
public void method3() throws CException
{
method1();
}
// 以下省略
// ...
}
  在这三个method 中,我们看到了method1 和method2 的程序码内都会产生Exception,但method3 的程序码中(大括号内),并没产生Exception,但在method3 的定义中,暗示了这个method 可能产生CException。
呼叫method1() 的程序,必须将method1() 包含在try 与catch 中,如:
public class runtest
{
// ....
public static void main(String argv[])
{
testException te = new testException();
try
{
te.method1();
}
catch(CException ce)
{
// ....
}
}
// ...
}
  虽然包含在try 与catch 中,并不表示这段程序码一定会收到CException,但它的用意在于提醒呼叫者,执行这个method 可能产生的意外,而使用者也必须要能针对这个意外做出相对应的处理方式。
  当使用者呼叫method2() 时,并不需要使用try 和catch 将程序码包起来,因为method2 的定义中,并没有throws 任何的Exception ,如:
public class runtest
{
// ....
public static void main(String argv[])
{
testException te = new testException();
// 不会产生 Exception
te.method2("Hello");
// 会产生 Exception
te.method2(null);
}
// ...
}
  程序在执行的时候,也不见得会真的产生NullPointerException ,这种Exception 叫做runtime exception 也有人称为unchecked exception ,产生Runtime Exception 的method (在这个范例中是method2) 并不需要在宣告method 的时候定义它将会产生哪一种Exception 。
在testException 的method3() 中,我们看到了另外一种状况,也就是method3里呼叫了method1() ,但却没有将method1 包在try 和catch 之间。相反,在method3() 的定义中,它定义了CException,实际上就是假如method3 收到了CException ,它将不处理这个CException ,而将它往外丢。当然,由于method3 的定义中有throws CException ,因此呼叫method3 的程序码也需要有try catch 才行。
  因此从程序的运作机制上看,Runtime Exception与Checked Exception 不一样,然而从逻辑上看,Runtime Exception 与Checked Exception 在使用的目的上也不一样。
  一般而言,Checked Exception 表示这个Exception 必须要被处理,也就是说程序设计者应该已经知道可能会收到某个Exception(因为要try catch住) ,所以程序设计者应该能针对这些不同的Checked Exception 做出不同的处理。
posted @ 2014-01-06 11:33 Eric_jiang 阅读(266) | 评论 (0)编辑 收藏

Java定义二维数组的几种写法
//写法1:先声明,然后new申请空间,最后赋值
  class numthree
  {
  public static void main(String[] args)
  {
  float[][] numthree;             //定义一个float类型的2维数组
  numthree=new float[5][5];       //为它分配5行5列的空间大小
  numthree[0][0]=1.1f;            //通过下标索引去访问     1行1列=1.1
  numthree[1][0]=1.2f;                                  // 2行1列=1.2
  numthree[2][0]=1.3f;                                  // 3行1列=1.3
  numthree[3][0]=1.4f;                                  // 4行1列=1.4
  numthree[4][0]=1.5f;                                  // 5行1列=1.5
  System.out.println(numthree[0][0]); //打印换行输出喽
  System.out.println(numthree[1][0]);
  System.out.println(numthree[2][0]);
  System.out.println(numthree[3][0]);
  System.out.println(numthree[4][0]);
  }
  }
 
//写法2:定义的同时分配空间大小
  class numfour
  {
  public static void main(String[] args)
  {
  short[][] numfour=new short[5][8]; //定义一个short类型的数组同时为它分配5行8列的空间大小
  numfour[0][7]=10;
  numfour[1][6]=20;
  numfour[2][5]=30;
  numfour[3][4]=40;
  numfour[4][3]=50;
  System.out.println(numfour[0][7]);
  System.out.println(numfour[1][6]);
  System.out.println(numfour[2][5]);
  System.out.println(numfour[3][4]);
  System.out.println(numfour[4][3]);
  }
  }
 
//写法3:不规则数组
  class numfive
  {
  public static void main(String[] args)
  {
  long[][] numfive=new long[5][];     //定义一个long类型的不规则数组
  numfive[0]=new long[5];             //为第1行分配5列
  numfive[1]=new long[6];             //为第2行分配6列
  numfive[2]=new long[7];             //为第3行分配7列
  numfive[3]=new long[8];             //为第4行分配8列
  numfive[4]=new long[9];             //为第5行分配9列
  numfive[0][4]=10000000000L;         //1行5列=10000000000
  numfive[1][5]=20000000000L;         //2行6列=20000000000
  numfive[2][6]=30000000000L;         //3行7列=30000000000
  numfive[3][7]=40000000000L;         //4行8列=40000000000
  numfive[4][8]=50000000000L;         //5行9列=50000000000
  System.out.println(numfive[0][4]); //打印换行输出喽
  System.out.println(numfive[1][5]);
  System.out.println(numfive[2][6]);
  System.out.println(numfive[3][7]);
  System.out.println(numfive[4][8]);
  System.out.println(numfive[4][7]); //打印输出一个没有定义数组元素的数组 java会自动将他初始化值为0
  }
  }
 
//写法4:定义的同时赋初始值
  class numsix
  {
  public static void main(String[] args)
  {
  double[][] numsix={{1.111D,2.222D,3.333D},{4.444D,5.555D,6.666D}};           //定义double型的数组分配3行3列的空间同时赋值
  System.out.println(numsix[0][0]); //打印换行输出1行1列=1.111
  System.out.println(numsix[1][1]); //打印换行输出2行2列=5.555
  }
  }
 
//写法5:定义不规则的2维数组同时赋初始值
  class numseven
  {
  public static void main(String[] args)
  {
  int[][] numseven=new int[][]{{10,20,30},{40,50},{60}};            //没什么好说的如果你在看不懂 那就别学了!
  System.out.println(numseven[0][2]);
  System.out.println(numseven[1][1]);
  System.out.println(numseven[0][0]);
  }
  }
 
//写法6:定义不规则的2维数组同时赋初始值
  class numeight
  {
  public static void main(String[] args)
  {
  int[][] numeight={{100,200,300,400},{500,600,700,800},{900,1000,1100,1200,1300}};
  System.out.println(numeight[0][2]);
  System.out.println(numeight[1][2]);
  System.out.println(numeight[2][1]);
  }
  }
posted @ 2014-01-03 11:16 Eric_jiang 阅读(3129) | 评论 (0)编辑 收藏

程序员可以使用两种import语句:

  单类型导入(single-type-import),例如import java.io.File;

  按需类型导入(type-import-on-demand),例如 import java.io.*;

  关于这两种导入类型大家各有所爱,众说纷纭。这里分析一下这两种导入类型的大致工作原理供大家参考。

  单类型导入比较好理解,仅仅导入一个public类或者接口。而对于按需类型导入,有人误解为导入一个包下的所有类,其实不然,看名字就知道,他只会按需导入,也就是说它并非导入整个包,而仅仅导入当前类需要使用的类。

  既然如此是不是就可以放心的使用按需类型导入呢?非也,非也。因为单类型导入和按需类型导入对类文件的定位算法是不一样的。

  java编译器会从启动目录(bootstrap),扩展目录(extension)和用户类路径下去定位需要导入的类,而这些目录仅仅是给出了类的顶层目录。编译器的类文件定位方法大致可以理解为如下公式:

  顶层路径名 \ 包名 \ 文件名.class = 绝对路径

  对于单类型导入很简单,因为包明和文件名都已经确定,所以可以一次性查找定位。

  对于按需类型导入则比较复杂,编译器会把包名和文件名进行排列组合,然后对所有的可能性进行类文件查找定位。例如:

  package com;

  import java.io.*;

  import java.util.*;

  当你的类文件中用到了File类,那么可能出现File类的地方如下:

  1、File \ File类属于无名包,就是说File类没有package语句,编译器会首先搜索无名包

  2、com.File \ File类属于当前包

  3、java.lang.File \编译器会自动导入java.lang包

  4、java.io.File

  5、java.util.File

  需要注意的地方就是,编译器找到java.io.File类之后并不会停止下一步的寻找,而要把所有的可能性都查找完以确定是否有类导入冲突。假设此时的顶层路径有三个,那么编译器就会进行3*5=15次查找。

  了解以上原理之后,我们可以得出这样的结论:按需类型导入是绝对不会降低Java代码的执行效率的,但会影响到Java代码的编译速度。

  查看JDK的源代码就知道SUN的软件工程师一般不会使用按需类型导入。因为使用单类型导入至少有以下两点好处:

  1。提高编译速度。

  2。避免命名冲突。(例如:当你import java.awt.*;import java.util.*后,使用List的时候编译器将会出编译错误)

  当然,使用单类型导入会使用你的import语句看起来很长。

posted @ 2014-01-03 10:25 Eric_jiang 阅读(171) | 评论 (0)编辑 收藏

Thread.start()与Thread.run()有什么区别?
run()方法,用于封装线程运行的任务代码。直接用创建的线程对象调用,并没有产生新的线程,仅仅是当前正在运行的线程(如,主线程)在执行run方法.
start()方法,共有两个作用,1,开启了当前线程,也就是说,当前程序又多了一条执行路径和当前线程(主线程)并发执行。而run()方法会被新开启的线程运行。2,调用线程的run()方法。
posted @ 2014-01-03 10:18 Eric_jiang 阅读(201) | 评论 (0)编辑 收藏

一般大家都知道ArrayList和LinkedList的大致区别: 
     1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
     2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
     3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 

ArrayList和LinkedList是两个集合类,用于存储一系列的对象引用(references)。例如我们可以用ArrayList来存储一系列的String或者Integer。那么ArrayList和LinkedList在性能上有什么差别呢?什么时候应该用ArrayList什么时候又该用LinkedList呢?


一.时间复杂度 
首先一点关键的是,ArrayList的内部实现是基于基础的对象数组的,因此,它使用get方法访问列表中的任意一个元素时(random access),它的速度要比LinkedList快。LinkedList中的get方法是按照顺序从列表的一端开始检查,直到另外一端。对LinkedList而言,访问列表中的某个指定元素没有更快的方法了。 
假设我们有一个很大的列表,它里面的元素已经排好序了,这个列表可能是ArrayList类型的也可能是LinkedList类型的,现在我们对这个列表来进行二分查找(binary search),比较列表是ArrayList和LinkedList时的查询速度,看下面的程序: 

  1. package com.mangocity.test;   
  2. import java.util.LinkedList;   
  3. import java.util.List;   
  4. import java.util.Random;   
  5. import java.util.ArrayList;   
  6. import java.util.Arrays;   
  7. import java.util.Collections;   
  8. public class TestList ...{   
  9.      public static final int N=50000;   
  10.   
  11.      public static List values;   
  12.   
  13.      static...{   
  14.          Integer vals[]=new Integer[N];   
  15.   
  16.          Random r=new Random();   
  17.   
  18.          for(int i=0,currval=0;i<N;i++)...{   
  19.              vals=new Integer(currval);   
  20.              currval+=r.nextInt(100)+1;   
  21.          }   
  22.   
  23.          values=Arrays.asList(vals);   
  24.      }   
  25.   
  26.      static long timeList(List lst)...{   
  27.          long start=System.currentTimeMillis();   
  28.          for(int i=0;i<N;i++)...{   
  29.              int index=Collections.binarySearch(lst, values.get(i));   
  30.              if(index!=i)   
  31.                  System.out.println("***错误***");   
  32.          }   
  33.          return System.currentTimeMillis()-start;   
  34.      }   
  35.      public static void main(String args[])...{   
  36.          System.out.println("ArrayList消耗时间:"+timeList(new ArrayList(values)));   
  37.          System.out.println("LinkedList消耗时间:"+timeList(new LinkedList(values)));   
  38.      }   
  39. }   

 

我得到的输出是:ArrayList消耗时间:15 
                 LinkedList消耗时间:2596 
这个结果不是固定的,但是基本上ArrayList的时间要明显小于LinkedList的时间。因此在这种情况下不宜用LinkedList。二分查找法使用的随机访问(random access)策略,而LinkedList是不支持快速的随机访问的。对一个LinkedList做随机访问所消耗的时间与这个list的大小是成比例的。而相应的,在ArrayList中进行随机访问所消耗的时间是固定的。 
这是否表明ArrayList总是比LinkedList性能要好呢?这并不一定,在某些情况下LinkedList的表现要优于ArrayList,有些算法在LinkedList中实现时效率更高。比方说,利用Collections.reverse方法对列表进行反转时,其性能就要好些。 
看这样一个例子,加入我们有一个列表,要对其进行大量的插入和删除操作,在这种情况下LinkedList就是一个较好的选择。请看如下一个极端的例子,我们重复的在一个列表的开端插入一个元素: 
Java代码  收藏代码
  1. package com.mangocity.test;   
  2.   
  3. import java.util.*;   
  4. public class ListDemo {   
  5.      static final int N=50000;   
  6.      static long timeList(List list){   
  7.      long start=System.currentTimeMillis();   
  8.      Object o = new Object();   
  9.      for(int i=0;i<N;i++)   
  10.          list.add(0, o);   
  11.      return System.currentTimeMillis()-start;   
  12.      }   
  13.      public static void main(String[] args) {   
  14.          System.out.println("ArrayList耗时:"+timeList(new ArrayList()));   
  15.          System.out.println("LinkedList耗时:"+timeList(new LinkedList()));   
  16.      }   
  17. }   

 这时我的输出结果是:ArrayList耗时:2463


                           LinkedList耗时:15 
这和前面一个例子的结果截然相反,当一个元素被加到ArrayList的最开端时,所有已经存在的元素都会后移,这就意味着数据移动和复制上的开销。相反的,将一个元素加到LinkedList的最开端只是简单的未这个元素分配一个记录,然后调整两个连接。在LinkedList的开端增加一个元素的开销是固定的,而在ArrayList的开端增加一个元素的开销是与ArrayList的大小成比例的。


二.空间复杂度 
在LinkedList中有一个私有的内部类,定义如下:

Java代码  收藏代码
  1. private static class Entry {   
  2.          Object element;   
  3.          Entry next;   
  4.          Entry previous;   
  5.      }   

 
每个Entry对象reference列表中的一个元素,同时还有在LinkedList中它的上一个元素和下一个元素。一个有1000个元素的LinkedList对象将有1000个链接在一起的Entry对象,每个对象都对应于列表中的一个元素。这样的话,在一个LinkedList结构中将有一个很大的空间开销,因为它要存储这1000个Entity对象的相关信息。 
ArrayList使用一个内置的数组来存储元素,这个数组的起始容量是10.当数组需要增长时,新的容量按如下公式获得:新容量=(旧容量*3)/2+1,也就是说每一次容量大概会增长50%。这就意味着,如果你有一个包含大量元素的ArrayList对象,那么最终将有很大的空间会被浪费掉,这个浪费是由ArrayList的工作方式本身造成的。如果没有足够的空间来存放新的元素,数组将不得不被重新进行分配以便能够增加新的元素。对数组进行重新分配,将会导致性能急剧下降。如果我们知道一个ArrayList将会有多少个元素,我们可以通过构造方法来指定容量。我们还可以通过trimToSize方法在ArrayList分配完毕之后去掉浪费掉的空间。


三.总结 
ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下: 
1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。


2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。


3.LinkedList不支持高效的随机元素访问。


4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间


可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。

posted @ 2014-01-03 10:12 Eric_jiang 阅读(205) | 评论 (0)编辑 收藏

        如果一个类的成员没有任何权限修饰,那么它门就是缺省包访问权限,用friendly来表示,注意friendly不是Java中的关键字,这里是个人喜欢的方式用它表示而已,有人喜欢说是default或者是pacakge,只是帮助理解。同一个包内其它类可以访问,但包外就不可以。对于同一个文件夹下的、没有用package的classes,Java会自动将这些classes初见为隶属于该目录的default package,可以相互调用class中的friendly成员。如以下两个class分别在同一个文件夹的两个文件中,虽然没有引入package,但隶属于相同的default package。
   class Sundae{
   //以下两个方法缺省为friendly
   Sundae(){}
   Void f() {System.out.println(“Sundae.f()”);
   }
   public class IceCream{
   public static void main(String[] args){
   Sundae x = new Sundae();
   x.f();
   }
   }
对于类来说:同一个包中的类可以用。总之,类只可以声明为public或者friendly。
posted @ 2014-01-03 09:56 Eric_jiang 阅读(227) | 评论 (0)编辑 收藏

<jsp:directive.page import="zero.space.ch03.BookBean"/>  
等效于
<%@ page import="zero.space.ch03.BookBean" %>  
但是有一点不同,如果你把所有类包的引入放在一个JSP中,在其他jsp中通include引入那个jsp。这时引入类就必须采用
<%@ page import="zero.space.ch03.BookBean" %>  
这样的写法。
<jsp:directive.page import="zero.space.ch03.BookBean"/>
这种写法只能在同一个jsp页面中使用,不能跨页调用
posted @ 2014-01-02 16:18 Eric_jiang 阅读(394) | 评论 (0)编辑 收藏

DOM 构建整个文档驻留内存的树。如果文档很大,就会要求有极大的内存。
DOM 创建表示原始文档中每个东西的对象,包括元素、文本、属性和空格。如果您只需关注原始文档的一小部分,那么创建那些永远不被使用的对象是极其浪费的。
DOM 解析器必须在您的代码取得控制权之前读取整个文档。对于非常大的文档,这会引起显著的延迟。
SAX 解析器向您的代码发送事件。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,它会告诉您。您可以决定什么事件对您重要,而且可以决定要创建什么类型的数据结构以保存来自这些事件的数据。如果您没有显式地保存来自某个事件的数据,它就被丢弃。
SAX 解析器根本不创建任何对象,它只是将事件传递给您的应用程序。如果希望基于那些事件创建对象,这将由您来完成。
SAX 解析器在解析开始的时候就开始发送事件。当解析器发现文档开始、元素开始和文本等时,代码会收到一个事件。您的应用程序可以立即开始生成结果;您不必一直等到整个文档被解析完毕。更妙的是,如果您只查找文档中某些内容,代码一旦找到所要找的东西就可以抛出一个异常。该异常会停止 SAX 解析器,然后代码用它找到的数据做它需要做的任何事。
SAX 事件是无状态的。当 SAX 解析器在 XML 文档中发现文本时,它就向您的代码发送一个事件。该事件仅仅给您发现的文本;它不告诉您什么元素包含那个文本。如果您想知道这一点,则必须自己编写状态管理代码。
SAX 事件不是持久的。如果应用程序需要一个数据结构来对 XML 文档建模,则必须自己编写那样的代码。如果您需要从 SAX 事件访问数据,并且没有把那个数据存储在代码中,那么您不得不再次解析该文档。
SAX 不是由一个集中管理的组织控制的。尽管到目前为止这还没有引起什么问题,但如果 SAX 是由象 W3C 这样的一个组织控制的话,有些开发人员会感觉更自在。
JDOM 的主要特性是它极大地减少了您必须编写的代码数量。JDOM 应用程序的长度通常是 DOM 应用程序的三分之一,大约是 SAX 应用程序的一半。
JAXP为使用 DOM、SAX 和 XSLT 处理 XML 文档提供公共接口

综述:SAX在对速度要求特别快,或机器内存不足的情况下使用;DOM在对解析速度要求不高,或xml文档不是很大的情况下使用;对于频繁修改xml文件内容的情况,建议用dom,因为sax每次都要从头到尾遍历节点,而且不易实现。虽然SAX表现较好,这要依赖于它特定的解析方式,一个 SAX 检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。
posted @ 2014-01-02 16:12 Eric_jiang 阅读(308) | 评论 (0)编辑 收藏

仅列出标题
共57页: First 上一页 11 12 13 14 15 16 17 18 19 下一页 Last