tbwshc

2013年7月15日 #

Java调用SQL Server的存储过程详解

1使用不带参数的存储过程

  1

  {call procedure-name}

  作为实例,在 SQL Server 2005 AdventureWorks 示例数据库中创建以下存储过程:

  CREATE PROCEDURE GetContactFormalNames

  AS BEGIN SELECT TOP 10 Title + ' ' + FirstName + ' ' + LastName AS FormalName

  FROM Person.Contact END

  此存储过程返回单个结果集,其中包含一列数据(由 Person.Contact 表中前十个联系人的称呼、名称和姓氏组成)。

  在下面的实例中,将向此函数传递 AdventureWorks 示例tb数据库的打开连接,然后使用 executeQuery 方法调用 GetContactFormalNames 存储过程。

  public static void executeSprocNoParams(Connection con)

  …{

  try …{

  Statement stmt = con.createStatement();

  ResultSet rs = stmt.executeQuery("{call dbo.GetContactFormalNames}");

  while (rs.next())

  …{

  System.out.println(rs.getString("FormalName"));

  }

  rs.close();

  stmt.close();

  }

  catch (Exception e)

  …{

  e.printStackTrace();

  }

  }

  2使用带有输入参数的存储过程

  使用 JDBC 驱动程序调用带参数的存储过程时,必须结合 SQLServerConnection 类的 prepareCall 方法使用 call SQL 转义序列。带有 IN 参数的 call 转义序列的语法如下所示:

  {call procedure-name[([parameter][,[parameter]]…)]}http://jie.baijiale.94ibc.com

  构造 call 转义序列时,请使用 ?(问号)字符来指定 IN 参数。此字符充当要传递给该存储过程的参数值的占位符。可以使用 SQLServerPreparedStatement 类的 setter 方法之一为参数指定值。可使用的 setter 方法由 IN 参数的数据类型决定。

  向 setter 方法传递值时,不仅需要指定要在参数中使用的实际值,还必须指定参数在存储过程中的序数位置。例如,如果存储过程包含单个 IN 参数,则其序数值为 1.如果存储过程包含两个参数,则第一个序数值为 1,第二个序数值为 2.

  作为如何调用包含 IN 参数的存储过程的实例,使用 SQL Server 2005 AdventureWorks 示例数据库中的 uspGetEmployeeManagers 存储过程。此存储过程接受名为 EmployeeID 的单个输入参数

posted @ 2013-10-24 17:05 chen11-1 阅读(617) | 评论 (0)编辑 收藏

Java中生成文件的10项建议

1. 记住 - "越少越好"并非总是如此(Keep in Mind – "Less is more" is not always better)。 – 高效率的代码是件好事,但很多情况下,并非代码行数越少效率就越高

  2. 不要把简单事情复杂化(Do not complicate things)。 – 我曾经这么做过,我相信你也一样。开发者都倾向于采用复杂方式解决简单问题。我们在一个只有5个用户的系统中引入EJB,为一个并不需要框架的应用实现一套框架,采用属性文件、采用面向tb对象解决方案、使用线程,而这些根本用不着。为什么会这么做?一些人可能不知道有更好的解决方案,但另一些人可能故意这样做来学习新知识,或仅仅是因为有趣。对那些不知道更好解决方案的人,要多听有经验程序员的建议。对于那些纯粹出于个人目的而将设计复杂化的人,我建议你要更加专业一点。
  3. 不要"硬编码"(No hard coding please)。 – 由于时间紧迫,开发者总是会忘记或故意忽略这一条。然而另一种可能是,遵循这条戒律,我们就不会陷入"时间紧迫"的困境。定义一个static final 变量,增加一行代码,又能花多长时间呢?

  4. 为代码添加注释(Add comments to your code)。 – 每个人都知道这一点,但不是每个人都会这么做。你有多少次"忘记"添加注释了?确实,注释不会为你的程序增加任何函数功能。但是,有多少次,看到2周前写的代码,你都记不起它是干什么的?你很幸运,那些未注释的代码是你自己写的,你脑海中还会有残存的印象。非常不幸,大多时候,代码是别人写的,并且那个人很可能已经离开公司了。有句谚语说的好:"有来有往,互惠互利",因此程序员应该体谅彼此(还有你自己),给你的代码加上注释。

 

posted @ 2013-10-24 17:04 chen11-1 阅读(314) | 评论 (0)编辑 收藏

针对Java Excel API及详细教程

时在java开发中会操作excel表格,其实操作起来也特别简单。这里把前期操作步骤说一下,本文会简单的介绍一个开放源码项目:Java Excel Api,使用它大家就可以方便的操作Excel文件了。

  首先下载好:Java Excel Api,这个文件我已经和 JAVA+Excel+API详细教程。pdf一并压缩上传了,感兴趣的朋友可以下载!

  我这里用的开发平台是Eclipse,这里我把操作简单说一下:

  1, 建,立java项目,在这个项目在建立一个新的文件夹lib;

  2, 将jxl.jar,即Java Excel Ap,复制到lib

  3,然后右键点击这个java项目,tb选择Propertieshttp://jie.baijiale.ibc198.com

  4,在左侧列表里选中Java Build Path ,右侧选中Libraries

  5,点击Add JARs

  6, 然后去选择这个项目中lib文件夹中的jxl.jar,点击确定

  成功后,项目中会多一个文件夹为:Referenced Libraries

  准备工作完成后,就可以去操作excel了,

posted @ 2013-10-24 17:02 chen11-1 阅读(278) | 评论 (0)编辑 收藏

框架Quart在Java中任务调度的使用

  Quartz框架是一个全功能、开源的任务调度服务,可以集成几乎任何的java应用程序—从小的单片机系统到大型的电子商务系统。Quartz可以执行上千上万的任务调度。

  核心概念

  Quartz核心的概念:scheduler任务调度、Job任务、Trigger触发器、JobDetail任务细节

  Job任务:其实Job是接口,其中只有一个execute方法:

  package org.quartz;

  public abstract interface Job

  {

  public abstract void execute(JobExecutionContext paramJobExecutionContext)

  throws JobExecutionException;

  }

  我们开发者只要实现此接口,实现execute方法即可。把我们想做的事情,在execute中执行即可。

  JobDetail:任务细节,Quartz执行Job时,需要新建个Job实例,但是不能直接操作Job类,所以通过JobDetail来获取Job的名称、描述信息。

  Trigger触发器:执行任务的规则;比如每天,每小时等。

  一般情况使用SimpleTrigger,和CronTrigger,这个触发器实现了Trigger接口。

  对于复杂的时间表达式来说,比如每个月15日上午几点几分,使用CronTrigger

  对于简单的时间来说,比如每天执行几次,使用SimpleTrigger

  scheduler任务调度:是最核心的概念,需要把JobDetail和Trigger注册到scheduler中,才可以执行。

  注意:

  不同的版本的jar包,具体的操作不太相同,但是tbw思路是相同的;比如1.8.6jar包中,JobDetail是个类,直接通过构造方法与Job类关联。SimpleTrigger和CornTrigger是类;在2.0.2jar包中,JobDetail是个接口,SimpleTrigger和CornTrigger是接口

  不同版本测试:

  1.8.6jar包:

  [html]

  package com.test;

  import java.util.Date;

  import org.quartz.Job;

  import org.quartz.JobExecutionContext;

  import org.quartz.JobExecutionException;

  /**

  * 需要执行的任务

  * @author lhy

  *

  */

  public class MyJob implements Job {

  @Override

  //把要执行的操作,写在execute方法中

  public void execute(JobExecutionContext arg0) throws JobExecutionException {

  System.out.println("测试Quartz"+new Date());

  }

  }

  package com.test;

  import java.util.Date;

  import org.quartz.Job;

  import org.quartz.JobExecutionContext;

  import org.quartz.JobExecutionException;

  /**

  * 需要执行的任务

  * @author lhy

  *

  */

  public class MyJob implements Job {

  @Override

  //把要执行的操作,写在execute方法中

  public void execute(JobExecutionContext arg0) throws JobExecutionException {

  System.out.println("测试Quartz"+new Date());

  }

  }

  使用SimpleTrigger触发器

  [html]

  package com.test;

  import java.util.Date;

  import org.quartz.JobDetail;

  import org.quartz.Scheduler;

  import org.quartz.SchedulerException;

  import org.quartz.SchedulerFactory;

  import org.quartz.SimpleTrigger;

  import org.quartz.impl.StdSchedulerFactory;

  /**

  * 调用任务的类

  * @author lhy

  *

  */

  public class SchedulerTest {

  public static void main(String[] args) {

  //通过schedulerFactory获取一个调度器

  SchedulerFactory schedulerfactory=new StdSchedulerFactory();

  Scheduler scheduler=null;

  try{

  // 通过schedulerFactory获取一个调度器

  scheduler=schedulerfactory.getScheduler();

  // 创建jobDetail实例,绑定Job实现类

  // 指明job的名称,所在组的名称,以及绑定job类

  JobDetail jobDetail=new JobDetail("job1", "jgroup1", MyJob.class);

  // 定义调度触发规则,比如每1秒运行一次,共运行8次

  SimpleTrigger simpleTrigger=new SimpleTrigger("simpleTrigger","triggerGroup");

  // 马上启动

  simpleTrigger.setStartTime(new Date());

  // 间隔时间

  simpleTrigger.setRepeatInterval(1000);

  // 运行次数

  simpleTrigger.setRepeatCount(8);

  // 把作业和触发器注册到任务调度中

  scheduler.scheduleJob(jobDetail, simpleTrigger);

  // 启动调度

  scheduler.start();

  }catch(SchedulerException e){

  e.printStackTrace();

  }

  }

  }

  package com.test;

  import java.util.Date;

  import org.quartz.JobDetail;

  import org.quartz.Scheduler;

  import org.quartz.SchedulerException;

  import org.quartz.SchedulerFactory;

  import org.quartz.SimpleTrigger;

  import org.quartz.impl.StdSchedulerFactory;

  /**

  * 调用任务的类

  * @author lhy

  *

  */

  public class SchedulerTest {

  public static void main(String[] args) {

  //通过schedulerFactory获取一个调度器

  SchedulerFactory schedulerfactory=new StdSchedulerFactory();

  Scheduler scheduler=null;

  try{

  // 通过schedulerFactory获取一个调度器

  scheduler=schedulerfactory.getScheduler();

  // 创建jobDetail实例,绑定Job实现类

  // 指明job的名称,所在组的名称,以及绑定job类
 JobDetail jobDetail=new JobDetail("job1", "jgroup1", MyJob.class);

  // 定义调度触发规则,比如每1秒运行一次,共运行8次

  SimpleTrigger simpleTrigger=new SimpleTrigger("simpleTrigger","triggerGroup");

  // 马上启动

  simpleTrigger.setStartTime(new Date());

  // 间隔时间

  simpleTrigger.setRepeatInterval(1000);

  // 运行次数

  simpleTrigger.setRepeatCount(8);

  // 把作业和触发器注册到任务调度中

  scheduler.scheduleJob(jobDetail, simpleTrigger);

  // 启动调度

  scheduler.start();

  }catch(SchedulerException e){

  e.printStackTrace();

  }

  }

  } 若使用CornTrigger触发器:

  [html]

  package com.test;

  import java.util.Date;

  import org.quartz.CronTrigger;

  import org.quartz.JobDetail;

  import org.quartz.Scheduler;

  import org.quartz.SchedulerException;

  import org.quartz.SchedulerFactory;

  import org.quartz.SimpleTrigger;

  import org.quartz.impl.StdSchedulerFactory;

  /**

  * 调用任务的类

  * @author lhy

  *

  */

  public class CronTriggerTest {

  public static void main(String[] args) {

  //通过schedulerFactory获取一个调度器

  SchedulerFactory schedulerfactory=new StdSchedulerFactory();

  Scheduler scheduler=null;

  try{

  // 通过schedulerFactory获取一个调度器

  scheduler=schedulerfactory.getScheduler();

  // 创建jobDetail实例,绑定Job实现类

  // 指明job的名称,所在组的名称,以及绑定job类

  JobDetail jobDetail=new JobDetail("job1", "jgroup1", MyJob.class);

  // 定义调度触发规则,每天上午10:15执行

  CronTrigger cornTrigger=new CronTrigger("cronTrigger","triggerGroup");

  // 执行规则表达式

  cornTrigger.setCronExpression("0 15 10 * * ? *");

  // 把作业和触发器注册到任务调度中

  scheduler.scheduleJob(jobDetail, cornTrigger);

  // 启动调度

  scheduler.start();

  }catch(Exception e){

  e.printStackTrace();

  }

  }

  }

  package com.test;

  import java.util.Date;

  import org.quartz.CronTrigger;

  import org.quartz.JobDetail;

  import org.quartz.Scheduler;

  import org.quartz.SchedulerException;

  import org.quartz.SchedulerFactory;

  import org.quartz.SimpleTrigger;

  import org.quartz.impl.StdSchedulerFactory;

  /**

  * 调用任务的类

  * @author lhy

  *

  */

  public class CronTriggerTest {

  public static void main(String[] args) {

  //通过schedulerFactory获取一个调度器

  SchedulerFactory schedulerfactory=new StdSchedulerFactory();

  Scheduler scheduler=null;

  try{

  // 通过schedulerFactory获取一个调度器

  scheduler=schedulerfactory.getScheduler();

  // 创建jobDetail实例,绑定Job实现类

  // 指明job的名称,所在组的名称,以及绑定job类

  JobDetail jobDetail=new JobDetail("job1", "jgroup1", MyJob.class);

  // 定义调度触发规则,每天上午10:15执行

  CronTrigger cornTrigger=new CronTrigger("cronTrigger","triggerGroup");

  // 执行规则表达式

  cornTrigger.setCronExpression("0 15 10 * * ? *");

  // 把作业和触发器注册到任务调度中

  scheduler.scheduleJob(jobDetail, cornTrigger);

  // 启动调度

  scheduler.start();

  }catch(Exception e){

  e.printStackTrace();

  }

  }

  }

  对于2.0.2jar包如下:

  其中的job类不变,主要是调度类如下:

  [html]

  package com.test;

  import java.util.Date;

  import org.quartz.CronScheduleBuilder;

  import org.quartz.JobBuilder;

  import org.quartz.JobDetail;

  import org.quartz.Scheduler;

  import org.quartz.SchedulerException;

  import org.quartz.SchedulerFactory;

  import org.quartz.SimpleScheduleBuilder;

  import org.quartz.Trigger;

  import org.quartz.TriggerBuilder;

  import org.quartz.impl.StdSchedulerFactory;

  /**

  * 调用任务的类

  * @author lhy

  *

  */

  public class SchedulerTest {

  public static void main(String[] args) {

  //通过schedulerFactory获取一个调度器

  SchedulerFactory schedulerfactory=new StdSchedulerFactory();

  Scheduler scheduler=null;

  try{

  // 通过schedulerFactory获取一个调度器

  scheduler=schedulerfactory.getScheduler();

  // 创建jobDetail实例,绑定Job实现类

  // 指明job的名称,所在组的名称,以及绑定job类

  JobDetail job=JobBuilder.newJob(MyJob.class).withIdentity("job1", "jgroup1").build();

  // 定义调度触发规则

  // 使用simpleTrigger规则

  // Trigger trigger=TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "triggerGroup")

  // .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withRepeatCount(8))

  // .startNow().build();

  // 使用cornTrigger规则 每天10点42分

  Trigger trigger=TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "triggerGroup")

  .withSchedule(CronScheduleBuilder.cronSchedule("0 42 10 * * ? *"))

  .startNow().build();

  // 把作业和触发器注册到任务调度中

  scheduler.scheduleJob(job, trigger);

  // 启动调度

  scheduler.start();

  }catch(Exception e){

  e.printStackTrace();

  }

  }

  }

  package com.test;

  import java.util.Date;

  import org.quartz.CronScheduleBuilder;

  import org.quartz.JobBuilder;

  import org.quartz.JobDetail;

  import org.quartz.Scheduler;

  import org.quartz.SchedulerException;

  import org.quartz.SchedulerFactory;

  import org.quartz.SimpleScheduleBuilder;

  import org.quartz.Trigger;

  import org.quartz.TriggerBuilder;

  import org.quartz.impl.StdSchedulerFactory;

  /**

  * 调用任务的类

  * @author lhy

  *

  */

  public class SchedulerTest {

  public static void main(String[] args) {

  //通过schedulerFactory获取一个调度器

  SchedulerFactory schedulerfactory=new StdSchedulerFactory();

  Scheduler scheduler=null;

  try{

  // 通过schedulerFactory获取一个调度器

  scheduler=schedulerfactory.getScheduler();

  // 创建jobDetail实例,绑定Job实现类

  // 指明job的名称,所在组的名称,以及绑定job类

  JobDetail job=JobBuilder.newJob(MyJob.class).withIdentity("job1", "jgroup1").build();

  // 定义调度触发规则

  // 使用simpleTrigger规则

  // Trigger trigger=TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "triggerGroup")

  // .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withRepeatCount(8))

  // .startNow().build();

  // 使用cornTrigger规则 每天10点42分

  Trigger trigger=TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "triggerGroup")

  .withSchedule(CronScheduleBuilder.cronSchedule("0 42 10 * * ? *"))

  .startNow().build();

  // 把作业和触发器注册到任务调度中

  scheduler.scheduleJob(job, trigger);

  // 启动调度

  scheduler.start();

  }catch(Exception e){

  e.printStackTrace();

  }

  }

  }

  上述demo下载:1.8版本demo下载

  2.0版本demo下载

  对于CornExpress讲解如下:

  字段 允许值 允许的特殊字符

  秒 0-59 , - * /

  分 0-59 , - * /

  小时 0-23 , - * /

  日期 1-31 , - * ? / L W C

  月份 1-12 或者 JAN-DEC , - * /

  星期 1-7 或者 SUN-SAT , - * ? / L C #

  年(可选) 留空, 1970-2099 , - * /

  表达式 意义

  "0 0 12 * * ?" 每天中午12点触发

  "0 15 10 ? * *" 每天上午10:15触发

  "0 15 10 * * ?" 每天上午10:15触发

  "0 15 10 * * ? *" 每天上午10:15触发

  "0 15 10 * * ? 2005" 2005年的每天上午10:15触发

  "0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发

  "0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发

  "0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发

  "0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发

  "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发

  "0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发

  "0 15 10 15 * ?" 每月15日上午10:15触发

  "0 15 10 L * ?" 每月最后一日的上午10:15触发

  "0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发

  "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发

  "0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发

  特殊字符 意义

  * 表示所有值;

  ? 表示未说明的值,即不关心它为何值;

  - 表示一个指定的范围;

  , 表示附加一个可能值;

  / 符号前表示开始时间,符号后表示每次递增的值;

  L("last") ("last") "L" 用在day-of-month字段意思是 "这个月最后一天";用在 day-of-week字段, 它简单意思是 "7" or "SAT"。 如果在day-of-week字段里和数字联合使用,它的意思就是 "这个月的最后一个星期几" – 例如: "6L" means "这个月的最后一个星期五". 当我们用“L”时,不指明一个列表值或者范围是很重要的,不然的话,我们会得到一些意想不到的结果。

  W("weekday") 只能用在day-of-month字段。用来描叙最接近指定天的工作日(周一到周五)。例如:在day-of-month字段用“15W”指“最接近这个月第15天的工作日”,即如果这个月第15天是周六,那么触发器将会在这个月第14天即周五触发;如果这个月第15天是周日,那么触发器将会在这个月第16天即周一触发;如果这个月第15天是周二,那么就在tbw触发器这天触发。注意一点:这个用法只会在当前月计算值,不会越过当前月。“W”字符仅能在day-of-month指明一天,不能是一个范围或列表。也可以用“LW”来指定这个月的最后一个工作日。

  # 只能用在day-of-week字段。用来指定这个月的第几个周几。例:在day-of-week字段用"6#3"指这个月第3个周五(6指周五,3指第3个)。如果指定的日期不存在,触发器就不会触发。

  C 指和calendar联系后计算过的值。例:在day-of-month 字段用“5C”指在这个月第5天或之后包括calendar的第一天;在day-of-week字段用“1C”指在这周日或之后包括calendar的第一天

posted @ 2013-09-17 15:15 chen11-1 阅读(2013) | 评论 (0)编辑 收藏

序列化在IO中读写对象的使用

    序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

  序列化的实现:将需要被序列化的类实现Serializable接口,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
 写对象和读对象的时候一定要使用序列化:

  import java.io.*;

  class Product implements Serializable {

  private static final long serialVersionUID = 1L;

  private float price;

  private float tax;

  public Product(float price) {

  this.price = price;

  tax = (float)(price*0.20);

  }

  public String toString() {

  return "price:"+price+",tax:"+tax;

  }

  }

  public class CmdDemo {

  public static void main(String[] strtb) throws Exception {

  Product p1 = new Product(100);

  ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream

  ("d:\product.txt"));

  os.writeObject(p1);

  os.close();

  ObjectInputStream is = new ObjectInputStream(new FileInputStream

  ("d:\product.txt"));

  Product p2 = (Product) is.readObject();

  System.out.println(p2.toString());

  }

  }

posted @ 2013-09-17 15:12 chen11-1 阅读(263) | 评论 (0)编辑 收藏

Java数组使用实用的技巧

  本文分享了关于Java数组最顶级的11大方法,帮助你解决工作流程问题,无论是运用在团队环境或是在私人项目中,你都可以直接拿来用!

0.  声明一个数组(Declare an array)
 
String[] aArray = new String[5];
String[] bArray = {"a","b","c", "d", "e"};
String[] cArray = new String[]{"a","b","c","d","e"};

1.  在Java中输出一个数组(Print an array in Java)
 
int[] intArray = { 1, 2, 3, 4, 5 };
String intArrayString = Arrays.toString(intArray);
 
// print directly will print reference value
System.out.println(intArray);
// [I@7150bd4d
 
System.out.println(intArrayString);
// [1, 2, 3, 4, 5]

2. 从数组中创建数组列表(Create an ArrayList from an array)
 
String[] stringArray = { "a", "b", "c", "d", "e" };
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(stringArray));
System.out.println(arrayList);
// [a, b, c, d, e]

3. 检查爱淘宝数组中是否包含特定值(Check if an array contains a certain value)
 
String[] stringArray = { "a", "b", "c", "d", "e" };
boolean b = Arrays.asList(stringArray).contains("a");
System.out.println(b);
// true
 
4. 连接两个数组( Concatenate two arrays)
 
int[] intArray = { 1, 2, 3, 4, 5 };
int[] intArray2 = { 6, 7, 8, 9, 10 };
// Apache Commons Lang library
int[] combinedIntArray = ArrayUtils.addAll(intArray, intArray2);
5. 声明一个数组内链(Declare an array inline )
 
method(new String[]{"a", "b", "c", "d", "e"});
 
6. 将数组元素加入到一个独立的字符串中(Joins the elements of the provided array into a single String)

// containing the provided list of elements
// Apache common lang
String j = StringUtils.join(new String[] { "a", "b", "c" }, ", ");
System.out.println(j);
// a, b, c
 
7. 将数组列表转换成一个数组 (Covnert an ArrayList to an array)
 
String[] stringArray = { "a", "b", "c", "d", "e" };
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(stringArray));
String[] stringArr = new String[arrayList.size()];
arrayList.toArray(stringArr);
for (String s : stringArr)
    System.out.println(s);
 
8. 将数组转换成一个集合(Convert an array to a set)
 
Set<String> set = new HashSet<String>(Arrays.asList(stringArray));
System.out.println(set);
//[d, e, b, c, a]
 
9. 反向数组(Reverse an array)
 
int[] intArray = { 1, 2, 3, 4, 5 };
ArrayUtils.reverse(intArray);
System.out.println(Arrays.toString(intArray));
//[5, 4, 3, 2, 1]
 
10. 删除数组元素(Remove element of an array)
 
int[] intArray = { 1, 2, 3, 4, 5 };
int[] removed = ArrayUtils.removeElement(intArray, 3);
//create a new array
System.out.println(Arrays.toString(removed));
 
One more – convert int to byte array
 
byte[] bytes = ByteBuffer.allocate(4).putInt(8).array();
 
for (byte t : bytes) {
   System.out.format("0x%x ", t);
}

posted @ 2013-09-17 15:08 chen11-1 阅读(257) | 评论 (0)编辑 收藏

Java动态代理设计模式

 所谓动态代理类是在运行时生成的class,在生成它时,你必须提供一组interface给它,则动态代理类就宣称它实现了这些interface。当然,动态代理类就充当一个代理,你不要企图它会帮你干实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
  下面通过实例来说明:
  Subject.java 抽象借口:声明代理对象和真实对象的共同接口
  [java]
  public interface Subject {
  public void doSomething();
  }
  public interface Subject {
  public void doSomething();
  }
  RealSubject.java 真实被tb代理对象
  [java]
  public class RealSubject implements Subject {
  @Override
  public void doSomething() {
  System.out.println("RealSubject.doSomething");
  }
  }
  public class RealSubject implements Subject {
  @Override
  public void doSomething() {
  System.out.println("RealSubject.doSomething");
  }
  }

  DynamicProxy.java 代理对象
  [java]
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Method;
  public class DynamicProxy implements InvocationHandler {
  private Object object;
  public DynamicProxy(Object object) {
  this.object = object;
  }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
  System.out.println("Before Invoke ! method : " + method);
  //我们可以再代理方法调用前后添加功能
  Object result = method.invoke(object, args);
  System.out.println("object : " + object + " result : " + result + " args : " + args);
  System.out.println("After Invoke !");
  return result;
  }
  }
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Method;
  public class DynamicProxy implements InvocationHandler {
  private Object object;
  public DynamicProxy(Object object) {
  this.object = object;
  }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
  System.out.println("Before Invoke ! method : " + method);
  //我们可以再代理方法调用前后添加功能
  Object result = method.invoke(object, args);
  System.out.println("object : " + object + " result : " + result + " args : " + args);
  System.out.println("After Invoke !");
  return result;
  }
  }
  Client.java 测试
  [java]
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Proxy;
  public class Client {
  public static void main(String[] args) throws Exception {
  //创建目标对象,也就是被代理对象
  RealSubject realSubject = new RealSubject();
  //将目标对象交给代理
  InvocationHandler handler = new DynamicProxy(realSubject);
  // Class proxyClass = Proxy.getProxyClass(Subject.class.getClassLoader()
  // , new Class[]{Subject.class});
  // Subject subject = (Subject)proxyClass.getConstructor(new Class[]{InvocationHandler.class})
  // .newInstance(new Object[]{handler});
  //返回代理对象,相当于上面两句
  Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
  realSubject.getClass().getInterfaces(),
  handler);
  //叫代理对象去doSomething(),其实在代理对象中的doSomething()中还是会
  //用handler来调用invoke(proxy, method, args) 参数proxy为调用者subject(this),
  //method为doSomething(),tb参数为方法要传入的参数,这里没有
  subject.doSomething();
  }
  }
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Proxy;
  public class Client {
  public static void main(String[] args) throws Exception {
  //创建目标对象,也就是被代理对象
  RealSubject realSubject = new RealSubject();
  //将目标对象交给代理
  InvocationHandler handler = new DynamicProxy(realSubject);
  // Class proxyClass = Proxy.getProxyClass(Subject.class.getClassLoader()
  // , new Class[]{Subject.class});
  // Subject subject = (Subject)proxyClass.getConstructor(new Class[]{InvocationHandler.class})
  // .newInstance(new Object[]{handler});
  //返回代理对象,相当于上面两句
  Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
  realSubject.getClass().getInterfaces(),
  handler);
  //叫代理对象去doSomething(),其实在代理对象中的doSomething()中还是会
  //用handler来调用invoke(proxy, method, args) 参数proxy为调用者subject(this),
  //method为doSomething(),参数为方法要传入的参数,这里没有
  subject.doSomething();
  }
  }
  打印结果:
  Before Invoke ! method : public abstract void Subject.doSomething()
  RealSubject.doSomething
  object : RealSubject@ec6b00 result : null args : null
  After Invoke !
  注意:
  Java动态代理涉及到的两个类:
  InvocationHandler:该接口中仅定义了一个Object : invoke(Object proxy, Method method, Object[] args);参数proxy指代理类,method表示被代理的方法,args为method中的参数数组,返回值Object为代理实例的方法调用返回的值。这个抽象方法在代理类中动态实现。
  Proxy:所有动态代理类的父类,提供用于创建动态代理类和实例的静态方法。

posted @ 2013-09-10 17:08 chen11-1 阅读(263) | 评论 (0)编辑 收藏

30条有用的 Java 编程规则

 (1) 类名首字母应该大写。字段、方法以及对象(句柄)的首字母应小写。对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字 母。例如:
  ThisIsAClassName
  thisIsMethodOrFieldName
  若在定义中出现了常数初始化字符,则大写static final基本类型标识符中的所有字母。这样便可标志出它们属于编译期的常数。
  Java包(Package)属于一种特殊情况:它们全都是小写字母,即便中间的单词亦是如此。对于域名扩展名称,如com,org,net或者edu 等,全部都应小写(这也是Java 1.1和Java 1.2的区别之一)。
  (2) 为了常规用途而创建一个类时,请采取“tb经典形式”,并包含对下述元素的定义:
  equals()
  hashCode()
  toString()
  clone()(implement Cloneable)
  implement Serializable
  (3) 对于自己创建的每一个类,都考虑置入一个main(),其中包含了用于测试那个类的代码。为使用一个项目中的类,我们没必要删除测试代码。若 进行了任何形式的改动,可方便地返回测试。这些代码也可作为如何使用类的一个示例使用。
  (4) 应将方法设计成简要的、功能性单元,用它描述和实现一个不连续的类接口部分。理想情况下,方法应简明扼要。若长度很大,可考虑通过某种方式将其分割成较短的几个方法。这样做也便于类内代码的重复使用(有些时候,方法必须非常大,但它们仍应只做同样的一件事情)。 (5) 设计一个类时,请设身处地为客户程序员考虑一下(类的使用方法应该是非常明确的)。然后,再设身处地为管理代码的人考虑一下(预计有可能进行哪些形式的修改,想想用什么方法可把它们变得更简单)。
  (6) 使类尽可能短小精悍,而且只解决一个特定的问题。下面是对类设计的一些建议:
  ■一个复杂的开关语句:考虑采用“多形”机制
  ■数量众多的方法涉及到类型差别极大的操作:考虑用几个类来分别实现
  ■许多成员变量在特征上有很大的差别:考虑使用几个类 。
  (7) 让一切东西都尽可能地“私有”——private。可使库的某一部分“公共化”(一个方法、类或者一个字段等等),就永远不能把它拿出。若强行拿出,就可能破坏其他人现有的代码,使他们不得不重新编写和设计。若只公布自己必须公布的,就可放心大胆地改变其他任何东西。在多线程环境中,隐私是特别重要的一个因素——只有private字段才能在非同步使用的情况下受到保护。
  (8) 谨惕“巨大对象综合症”。对一些习惯于顺序编程思维、且初涉OOP领域的新手,往往喜欢先写一个顺序执行的程序,再把它嵌入一个或两个巨大的 对象里。根据编程原理,对象表达的应该是应用程序的概念,而非应用程序本身。
  (9) 若不得已进行一些不太雅观的编程,至少应该把那些代码置于一个类的内部。
  (10) 任何时候只要发现类与类之间结合得非常紧密,就需要考虑是否采用内部类,从而改善编码及维护工作(参见第14章14.1.2小节的“用内部 类改进代码”)。
  (11) 尽可能细致地加上释,并用javadoc注释文档语法生成自己的程序文档。
  (12) 避免使用“魔术数字”,这些数字很难与代码很好地配合。如以后需要修改它,无疑会成为一场噩梦,因为根本不知道“100”到底是指“数组大小”还是“其他全然不同的东西”。所以,我们应创建一个常数,并为其使用具有说服力的描述性名称,并在整个程序中都采用常数标识符。这样可使程序更易理解以及更易维护。
  (13) 涉及构建器和异常的时候,通常希望重新丢弃在构建器中捕获的任何异常——如果它造成了那个对象的创建失败。这样一来,调用者就不会以为那个 对象已正确地创建,从而盲目地继续。
  (14) 当客户程序员用完对象以后,若你的类要求进行任何清除工作,可考虑将清除代码置于一个良好定义的方法里,采用类似于cleanup()这样的名字,明确表明自己的用途。除此以外,可在类内放置一个boolean(布尔)标记,指出对象是否已被清除。在类的finalize()方法里,请确定对象已被清除,并已丢弃了从RuntimeException继承的一个类(如果还没有的话),从而指出一个编程错误。在采取象这样的方案之前,请确定 finalize()能够在自己的系统中工作(可能需要调用System.runFinalizersonExit(true),从而确保 这一行为)。
  (15) 在一个特定的作用域内,若一个对象必须清除(非由tb垃圾收集机制处理),请采用下述方法:初始化对象;若成功,则立即进入一个含有 finally从句的try块,开始清除工作。
  (16) 若在初始化过程中需要覆盖(取消)finalize(),请记住调用super.finalize()(若Object属于我们的直接超类,则无此必要)。在对finalize()进行覆盖的过程中,对super.finalize()的调用应属于最后一个行动,而不应是第一个行动,这样可确保在需要基础类组件的时候它们依然有效。
  (17) 创建大小固定的对象集合时,请将它们传输至一个数组(若准备从一个方法里返回这个集合,更应如此操作)。这样一来,我们就可享受到数组在编 译期进行类型检查的好处。此外,为使用它们,数组的接收者也许并不需要将对象“造型”到数组里。
  (18) 尽量使用interfaces,不要使用abstract类。若已知某样东西准备成为一个基础类,那么第一个选择应是将其变成一个 interface(接口)。只有在不得不使用方法定义或者成员变量的时候,才需要将其变成一个abstract(抽象)类。接口主要描述了客户希望做什么事情,而一个类则致力于(或允许)具体的实施细节。
  (19) 在构建器内部,只进行那些将对象设为正确状态所需的工作。尽可能地避免调用其他方法,因为那些方法可能被其他人覆盖或取消,从而在构建过程 中产生不可预知的结果(参见第7章的详细说明)。
  (20) 对象不应只是简单地容纳一些数据;它们的行为也应得到良好的定义。
  (21) 在现成类的基础上创建新类时,请首先选择“新建”或“创作”。只有自己的设计要求必须继承时,才应考虑这方面的问题。若在本来允许新建的场 合使用了继承,则整个设计会变得没有必要地复杂。
  (22) 用继承及方法覆盖来表示行为间的差异,而用字段表示状态间的区别。一个非常极端的例子是通过对不同类的继承来表示颜色,这是绝对应该避免 的:应直接使用一个“颜色”字段。

  (23) 为避免编程时遇到麻烦,请保证在自己类路径指到的任何地方,每个名字都仅对应一个类。否则,编译器可能先找到同名的另一个类,并报告出错消 息。若怀疑自己碰到了类路径问题,请试试在类路径的每一个起点,搜索一下同名的.class文件。
  (24) 在Java 1.1 AWT 中使用事件“适配器”时,特别容易碰到一个陷阱。若覆盖了某个适配器方法,同时拼写方法没有特别讲究,最后的结果就是新添加一个方法,而不是覆盖现成方法。然而,由于这样做是完全合法的,所以不会从编译器或运行期系统获得任何出错提示——只不过代码的工作就变得不正常了。
  (25) 用合理的设计方案消除“伪功能”。也就是说,假若只需要创建类的一个对象,就不要提前限制自己使用应用程序,并加上一条“只生成其中一个 ” 注释。请考虑将其封装成一个“独生子”的形式。若在主程序里有大量散乱的代码,用于创建自己的对象,请考虑采纳一种创造性的方案,将些代码封装起来。
  (26) 警惕“分析瘫痪”。请记住,无论如何都要提前了解整个项目的状况,再去考察其中的细节。由于把握了全局,可快速认识自己未知的一些因素,防 止在考察细节的时候陷入“死逻辑”中。
  (27) 警惕“过早优化”。首先让它运行起来,再考虑变得更快——但只有在自己必须这样做、而且经证实在某部分代码中的确存在一个性能瓶颈的时候, 才应进行优化。除非用专门的工具分析瓶颈,否则很有可能是在浪费自己的时间。性能提升的隐含代价是自己的代码变得难于理解,而且难于维护。
  (28) 请记住,阅读代码的时间比写代码的时间多得多。思路清晰的设计可获得易于理解的程序,但注释、细致的解释以及一些示例往往具有不可估量的价 值。无论对你自己,还是对后来的人,它们都是相当重要的。如对此仍有怀疑,那么请试想自己试图从联机Java文档里找出有用信息时碰到的挫折,这样或许能 将你说服。
  (29) 如认为自己已进行了良好的分析、设计或者实施,那么请稍微更换一下思维角度。试试邀请一些外来人士——并不一定是专家,但可以是来自本公司其他部门的人。请他们用完全新鲜的眼光考察你的工作,看看是否能找出你一度熟视无睹的问题。采取这种方式,往往能在最适合修改的阶段找出一些关键性的问题,避免产品发行后再解决问题而造成的金钱及精力方面的损失。
  (30) 良好的设计能带来最大的回报。简言之,对于一个特定的问题,通常会花较长的时间才能找到一种最恰当的解决方案。但一旦找到了正确的方法,以后的工作就轻松多了,再也不用经历数小时、数天或者数月的痛苦挣扎。我们的努力工作会带来最大的回报(甚至无可估量)。而且由于自己倾注了大量心血,最终获得一个出色的设计方案,成功的快感也是令人心动的。坚持抵制草草完工的诱惑——那样做往往得不偿失

posted @ 2013-08-23 16:56 chen11-1 阅读(238) | 评论 (0)编辑 收藏

单多线程Java算法相比较

1进程和线程的概念
  1.1什么是进程
  一个进程就是在一个运行的程序,它有自己独立的内存空间,一组系统资源,每个进程的内部数据和状态都是独立的,例如在window是同时打开多个记事本,虽然它们所运行的程序代码都是一样的,但是所使用的内存空间是独立的,互不干扰.
  1.2什么是线程
  线程与进程相似,是一段完成某个特定功能的代码,是程序中单个顺序的流控制;但与进程不同的是,同类的多个线程共享一块内存空间和一组系统资源,而线程本身的数据通常只有微处理器的寄存器数据,以及一个供程序执行时使用的堆栈
  1.3进程与线程的区别
  1. 进程:每个进程都有独立的代码和数据空间(进程上下文) ,tb进程切换的开销大.
  2. 线程:轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小.
  3. 多进程:在操作系统中,能同时运行多个任务程序.
  4. 多线程:在同一应用程序中,有多个顺序流同时执行.
  1.4线程创建的两种方式
  采用继承Thread类创建线程
  该方法比较简单,主要是通过继承java.lang.Thread类,并覆盖Thread类的run()方法来完成线成的创建.Thread 类是一个具体的类,即不是抽象类,该类封装了线程的行为.要创建一个线程,程序员必须创建一个从 Thread 类导出的新类.Thread类中有两个最重要的函数run()和start().
  通过实现Runnable接口创建线程
  该方法通过生成实现java.lang.Runnable接口的类.该接口只定义了一个方法run(),所以必须在新类中实现它.但是 Runnable 接口并没有任何对线程的支持,我们还必须创建 Thread 类的实例,这一点通过 Thread 类的构造函数
  public Thread(Runnable target);来实现.
  2 单线程和多线程性能比较
  以使用蒙特卡罗概率算法求π为例,进行单线程和多线程时间比较
  2.1什么是蒙特卡罗概率算法

  蒙特卡罗法(Monte Carlo method)是以概率和统计的理论、方法为基础的一种计算方法,将所求解的问题同一定的概率模型相联系,用电子计算机实现统计模拟或抽样,以获得问题的近似解,故又称统计模拟法或统计试验法. --百度百科
  蒙特卡罗求算法求π
  第一步
  画正方形和内切圆
  第二步
  变换表达式
  正方形面积As=(2R)^2
  圆的面积Ac=πR^2
  Ac/As=(2R)^2/πR^2
  π=4As/Ac
  令P=As/Sc,则π=4P
  第三步
  重复N次实验求平均值
  在正方形区域内随机生成一个点A,若A落在圆区域内,M++
  P=M/N
  π=4P,N的取值越大,π的值越精确
  2.2 java代码实现算法
  N取值为10000万,多线程的数为100,每个线程执行100万次模拟实验
  线程实现
  import java.util.concurrent.CountDownLatch;
  public class ProModel implements Runnable {
  public int N;//随机实验的总次数
  public static int M;//随机点落在圆中的次数
  private int id;
  private final CountDownLatch doneSignal;
  OBJ semaphore;
  public ProModel(int id,CountDownLatch doneSignal,int N,OBJ semaphore2){
  this.id=id;
  this.doneSignal=doneSignal;
  this.N=N;
  this.semaphore=semaphore2;
  M=0;
  }
  public void run(){
  int tempM=0;
  for(int i=0;i
  if(isInCircle()){
  tempM++;
  }
  }
  synchronized (semaphore) {
  add(tempM);
  }
  doneSignal.countDown();//使end状态减1
  }
  public void add(int tempM){
  System.out.println(Thread.currentThread().getName());
  M=M+tempM;
  System.out.println(M);
  }
  //随机产生一个在正方形区域的点,判断它是否在圆中
  public boolean isInCircle(){
  double x=Math.random();
  double y=Math.random();
  if((x-0.5)*(x-0.5)+(y-0.5)*(y-0.5)<0.25)
  return true;
  else
  return false;
  }
  public static int getTotal(){
  return M;
  }
  }
  多线程Main实现
  import java.util.concurrent.CountDownLatch;
  import java.util.concurrent.ExecutorService;
  import java.util.concurrent.Executors;
  public class MutliThread {
  public static void main(String[] args) throws InterruptedException {
  long begin=System.currentTimeMillis();
  int threadSize=100;
  int N=1000000;
  OBJ semaphore = new OBJ();
  CountDownLatch doneSignal = new CountDownLatch(threadSize);
  ProModel[] pros=new ProModel[threadSize];
  //设置特定的线程池,大小为threadSizde
  System.out.println(“begins!”);
  ExecutorService exe = Executors.newFixedThreadPool(threadSize);
  for(int i=0;i
  exe.execute(new ProModel(i+1,doneSignal,N,semaphore));
  try{
  doneSignal.await(); //等待end状态变为0, }catch (InterruptedException e) {
  // TODO: handle exception35
  e.printStackTrace();
  }finally{
  System.out.println(“ends!”);
  System.out.println(4*(float)ProModel.getTotal()/(float)(threadSize*N));
  }
  exe.shutdown();
  long end=System.currentTimeMillis();
  System.out.println(“used time(ms):”+(end-begin));
  }
  }
  class OBJ{}
  单线程Main实现
  import java.util.concurrent.CountDownLatch;
  import java.util.concurrent.ExecutorService;
  import java.util.concurrent.Executors;
  public class SingleThread {
  public static void main(String[] args) {
  long begin=System.currentTimeMillis();
  int threadSize=1;
  int N=100000000;
  OBJ semaphore = new OBJ();
  CountDownLatch doneSignal = new CountDownLatch(threadSize);
  ProModel[] pros=new ProModel[threadSize];
  //设置特定的线程池,大小为5
  System.out.println(“begins!”);
  ExecutorService exe = Executors.newFixedThreadPool(threadSize);
  for(int i=0;i
  exe.execute(new ProModel(i+1,doneSignal,N,semaphore));
  try{
  doneSignal.await(); //等待end状态变为0, }catch (InterruptedException e) {
  // TODO: handle exception35
  e.printStackTrace();
  }finally{
  System.out.println(“ends!”);
  System.out.println(4*(float)ProModel.getTotal()/(float)(threadSize*N));
  }
  exe.shutdown();
  long end=System.currentTimeMillis();
  System.out.println(“used time(ms):”+(end-begin));
  }
  }

posted @ 2013-08-23 16:54 chen11-1 阅读(257) | 评论 (0)编辑 收藏

Arrays.asList方法 学习记录

Arrays工具类提供了一些比较实用的方法,比如sort, binarySearch, fill等。其中还有一个asList方法,此方法能够将一个变长参数或者数组转换成List。
  但是,这个生成的List,它是固定长度的,如果对其进行add或者remove的操作,会抛出UnsupportedOperationException,为什么会这样呢?
  带着疑问,查看一下Arrays的源码,可以得到问题的结果。
  Java代码
  /**
  * Returns a fixed-size list backed by the specified array. (Changes to
  * the returned list "write through" to the array.) This method acts
  * as bridge between array-based and collection-based APIs, in
  * combination with Collection.toArray. The returned list is
  * serializable and implements {@link RandomAccess}.
  *
  *
  This method also provides a convenient way to create a fixed-size
  * list initialized to contain several elements:
  *
  * List stooges = Arrays.asList("Larry", "Moe", "Curly");
  *
  *
  * @param a the array by which the list will be backed.
  * @return a list view of the specified array.
  * @see Collection#toArray()
  */
  public static List asList(T... a) {
  return new ArrayList(a);

  方法asList返回的是new ArrayList(a)。但是,这个ArrayList并不是java.util.ArrayList,它是一个Arrays类中的重新定义的内部类。
  具体的实现如下:
  Java代码
  /**
  * @serial include
  */
  private static class ArrayList extends AbstractList
  implements RandomAccess, java.io.Serializable
  {
  private static final long serialVersionUID = -2764017481108945198L;
  private Object[] a;
  ArrayList(E[] array) {
  if (array==null)
  throw new NullPointerException();
  a = array;
  }
  public int size() {
  return a.length;
  }
  public Object[] toArray() {
  return (Object[])a.clone();
  }
  public E get(int index) {
  return (E)a[index];
  }
  public E set(int index, E element) {
  Object oldValue = a[index];
  a[index] = element;
  return (E)oldValue;
  }
  public int indexOf(Object o) {
  if (o==null) {
  for (int i=0; i
  if (a[i]==null)
  return i;
  } else {
  for (int i=0; i
  if (o.equals(a[i]))
  return i;
  }
  return -1;
  }
  public boolean contains(Object o) {
  return indexOf(o) != -1;
  }
  }
  从这个内部类ArrayList的实现可以看出,它继承了类AbstractList,但是没有重写add和remove方法,没有给出具体的实现。查看一下AbstractList类中对add和remove方法的定义,如果一个list不支持add和remove就会抛出UnsupportedOperationException。
  Java代码
  public abstract class AbstractList extends AbstractCollection implements List {
  /**
  * Sole constructor. (For invocation by subclass constructors, typically
  * implicit.)
  */
  protected AbstractList() {
  }
  /**
  * Appends the specified element to the end of this List (optional
  * operation).
  *
  * This implementation calls add(size(), o).
  *
  * Note that this implementation throws an
  * UnsupportedOperationException unless add(int, Object)
  * is overridden.
  *
  * @param o element to be appended to this list.
  *
  * @return true (as per the general contract of
  * Collection.add).
  *
  * @throws UnsupportedOperationException if the add method is not
  * supported by this Set.
  *
  * @throws ClassCastException if the class of the specified element
  * prevents it from being added to this set.
  *
  * @throws IllegalArgumentException some aspect of this element prevents
  * it from being added to this collection.
  */
  public boolean add(E o) {
  add(size(), o);
  return true;
  }
  /**
  * Inserts the specified element at the specified position in this list
  * (optional operation). Shifts the element currently at that position
  * (if any) and any subsequent elements to the right (adds one to their
  * indices).
  *
  * This implementation always throws an UnsupportedOperationException.
  *
  * @param index index at which the specified element is to be inserted.
  * @param element element to be inserted.
  *
  * @throws UnsupportedOperationException if the add method is not
  * supported by this list.
  * @throws ClassCastException if the class of the specified element
  * prevents it from being added to this list.
  * @throws IllegalArgumentException if some aspect of the specified
  * element prevents it from being added to this list.
  * @throws IndexOutOfBoundsException index is out of range (index <
  * 0 || index > size()).
  */
  public void add(int index, E element) {
  throw new UnsupportedOperationException();
  }
  /**
  * Removes the element at the specified position in this list (optional
  * operation). Shifts any subsequent elements to the left (subtracts one
  * from their indices). Returns the element that was removed from the
  * list.
  *
  * This implementation always throws an
  * UnsupportedOperationException.
  *
  * @param index the index of the element to remove.
  * @return the element previously at the specified position.
  *
  * @throws UnsupportedOperationException if the remove method is
  * not supported by this list.
  * @throws IndexOutOfBoundsException if the specified index is out of
  * range (index < 0 || index >= size()).
  */
  public E remove(int index) {
  throw new UnsupportedOperationException();
  }
  }
  至此,为什么Arrays.asList产生的List是不可添加或者删除,否则会产生UnsupportedOperationException,就可以得到解释了。
  如果我们想把一个变长或者数据转变成List, 而且tb期望这个List能够进行add或者remove操作,那该怎么做呢?
  我们可以写一个类似的方法,里面直接采用java.util.ArrayList即可。
  比如:
  Java代码
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;
  public class MyArrays {
  public static List asList(T... a) {
  List list = new ArrayList();
  Collections.addAll(list, a);
  return list;
  }
  }
  测试代码如下:
  Java代码
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  public class Test {
  @SuppressWarnings("unchecked")
  public static void main(String[] args) {
  List stooges = Arrays.asList("Larry", "Moe", "Curly");
  print(stooges);
  List> seasonsList = Arrays.asList(retrieveSeasonsList());
  print(seasonsList);
  /*
  * 自己实现一个asList方法,能够添加和删除。
  */
  List list = MyArrays.asList("Larry", "Moe", "Curly");
  list.add("Hello");
  print(list);
  }
  private static void print(List list) {
  System.out.println(list);
  }
  private static List retrieveSeasonsList() {
  List seasonsList = new ArrayList();
  seasonsList.add("Spring");
  seasonsList.add("Summer");
  seasonsList.add("Autumn");
  seasonsList.add("Winter");
  return seasonsList;
  }
  }
  输出结果:
  [Larry, Moe, Curly]
  [[Spring, Summer, Autumn, Winter]]
  [Larry, Moe, Curly, Hello]

posted @ 2013-07-15 17:08 chen11-1 阅读(229) | 评论 (0)编辑 收藏

Java集合框架中几种集合的分析

        集合可以理解为在内存中存放一组对象的容器,对象是数据的封装,而对象又构成了集合。在java中的集合框架是一种线性的数据结构,但是它分为两种,一种是物理结构,一种是逻辑结构。物理结构是一种连续存储的结构,比如说数组;而逻辑结构可以理解为在内存块中是不连续的,比如说链表,一个链表是分为两中内容的,一个是该链表所存储的数据,还有一个呢,那就是指向下一个链表的指针,通过指针而把表给连起来,称之为链表。数组其实也是可以完成像集合一样的存储的,但是数组存在一定的弊端,数组一旦创建,其大小,类型是固定的,在特定的情况下不能更方便的使用,因此,为了与数组互补,集合也就应运而生了。
  在java.util包中存在三种最重要的集合,其分别是list,set,map,它们各自有各自的特点,这三种都是接口。其中list:1> list的实现类主要有ArrayList,Linkedlist及其Vector,list中存储的数据是有序的,而且也是可以重复的,也就是说list按照添加的顺序,依次的tb存储在list下标从小到大的位置。做一个简单的代码测试
  public class Test {
  public static void main(String[] args) {
  Test test = new Test();
  test.testList();
  public void testList(){//类
  //创建一个List对象
  List list = new ArrayList();
  list.add(1);
  list.add(1);
  list.add(2);
  for(Object a:list){
  System.out.print(a+" ");
  }
  }
  此段代码的运行结果为:{1 1 2}
  反应了其有序可重复的特点。
  2>set同样是一个接口,它常用的实现类有Hashset,Treeset。set集合的存储特点可以说是和list完全相反的,它是一种无序而且不能重复的存储特点。同样的用代码做一个测试 public class Test {
  public static void main(String[] args) {
  Test test = new Test();
  test.testSet();
  public void testSet(){
  //创建Set对象
  Set set = new HashSet();
  set.add(1);
  set.add(2);
  set.add(5);
  set.add(3);
  set.add(4);
  set.add(1);
  set.add(null);
  System.out.println(set);
  Iterator it = set.iterator();
  while(it.hasNext()){//判断有元素可迭代
  int i = it.next();
  System.out.print(i+" ");
  }
  }
  }
  }

  此段代码的运行结果是:{1 2 3 4 5}
  可以说明其无序不可重复的特点。
  3>最后则是map集合,map的实现类常用的有Hashmap,Hashtable和Treemap。
  map与以上两者稍微的有点不同,它是一种映射关系,在map中,存储两种数据,tb表达为map,而以上两者都只有一个数据,而且都是通过下标来访问的,map中k是不可以重复的,而v是可以重复的,进行一段代码测试
  public class Test{
  public static void main(String[] args){
  testmap test=new testmap();
  public void testMap(){
  Map map = new HashMap();
  map.put(1, "aaa");
  map.put(2, "bbb");
  map.put(3,"ccc");
  map.put(2, "ddd");
  System.out.println(map);
  //获取key集合(Set)
  Set set = map.keySet();
  Iterator it = set.iterator();
  while(it.hasNext()){
  int key = it.next();
  //通过key获取对应的value值
  String value = map.get(key);
  System.out.println("key="+key+" value="+value);
  }
  }
  }
  }
  此段代码的运行结果是:key=1 value=aaa;key=2 value=ddd;key=3 value=ccc。
  这三种集合各有其所试用的地方,对于像我这种初学者可以让整个代码简化,思路更清晰。
  二:获得各种数据存储方式长度的方法。
  数组:定义一个数组Array[];那么获得该数组长度的方法是使用其length方法。
  字符串: String st = "aaa";
  st.length();
  这里的length是字符串的一种属性,而数组的length是一种方法。
  List:迭代或者直接通过下标输出,list.size()
  set:迭代while(it.hasNext()){//判断有元素可迭代
  int i = it.next();
  System.out.print(i+" ");
  }
  map:只能用迭代的方法,
  //获取key集合(Set)
  Set set = map.keySet();
  Iterator it = set.iterator();
  while(it.hasNext()){
  int key = it.next();
  //通过key获取对应的value值
  String value = map.get(key);
  System.out.println("key="+key+" value="+value);
  }
  map先是通过迭代器先得到key值,因为是一种一一对应的关系,所以用key值就可以得到value值了。

posted @ 2013-07-15 16:52 chen11-1 阅读(241) | 评论 (0)编辑 收藏