JAVA将字符串变为输入流

关于字符串转化为输入流,我找到2种方法:
1. 用StringReader将字符串转化为Reader
2. 用ByteArrayInputStream将字符串转化为InputStream. 还有一个类StringBufferInputStream也可以将String转化为InputStream,但是由于它只支持字符串中每个字符的低八位,所以已经被遗弃了。
PS: java.io.Reader 和 java.io.InputStream 组成了 Java 输入类。Reader 用于读入16位字符,也就是 Unicode 编码的字符;而 InputStream 用于读入 ASCII 字符和二进制数据。

示例代码如下:

 

转自:http://zben000.javaeye.com/blog/787562

Spring upload form optional with optional file

We are creating a profile page with a form that optionally has a profile pic on it. We are using Spring 3.2

Here is the form: –

Here is the controller method: –

Here is the Model

It works fine if a file is submitted on the form, but there are errors in the BindingResult variable if the form is submitted without a file.

Here is the error: –

======================

It turns out it was the jQuery Form plugin which was sending an empty string instead of what spring expects – nothing to be sent.

I solved the problem using a before submit to remove the fileData value if it wasn’t populated like so: –

I hope this helps some googlers with the same problem.

来自:http://stackoverflow.com/questions/14771446/spring-upload-form-optional-with-optional-file

Java的setScale与Javascript的toFixed

Javascript的toFixed() 方法可把 Number 四舍五入为指定小数位数的数字。
语法:NumberObject.toFixed(num)
参数:   num    必需。规定小数的位数,是 0 ~ 20 之间的值,包括 0  和 20,有些实现可以支持更大的数值范围。如果省略了该参数,将用 0 代替。

在Server端(Java)可使用BigDecimal的setScale实现相同的功能

setScale(2, BigDecimal.ROUND_HALF_UP);

其中,2为精确度,即保留几位小数;BigDecimal.ROUND_HALF_UP为舍入模式;

枚举常量摘要

  • CEILING  向正无限大方向舍入的舍入模式。
  • DOWN     向零方向舍入的舍入模式。
  • FLOOR    向负无限大方向舍入的舍入模式。
  • HALF_DOWN   向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。
  • HALF_EVEN    向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
  • HALF_UP    向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。
  • UNNECESSARY  用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。
  • UP  远离零方向舍入的舍入模式。

 

如果需要格式化数字,可使用new DecimalFormat(“格式”);

符号    意义
0          一个数位
#          一个数位,前导零和追尾零不显示
.           小数点分割位置
,        组分隔符的位置
–           负数前缀
%        用100乘,并显示百分号

 

摘于:
http://www.w3school.com.cn/js/jsref_tofixed.asp
http://stackoverflow.com/questions/10631813/javascript-tofixed-equivalent-in-java
http://volzengwen.blog.163.com/blog/static/1968163262011102405939123/

AIML机器人

AIML,全名为Artificial Intelligence Markup Language(人工智能标记语言),是一种创建自然语言软件代理的XML语言,是由Richard Wallace和世界各地的自由软件社区在1995年至2002年发明的。它的雏形是一个名为”A.L.I.C.E.” (“Artificial Linguistic Internet Computer Entity”)的高度扩展的Eliza机器人。ALICE总共赢得3次每年度的Loebner奖,并且在2004年获得了Chatterbox Challenge的冠军。由于A.L.I.C.E. 的AIML设置是在GNU GPL协议下发布的,所以已经有许多基于该程序和AIML库的“克隆ALICE”出现。目前AIML已经有了Java,Ruby,Python, C ,C#,Pascal等语言的版本。

例子:http://alice.mpabo.com

AIML文件就是一个xml兼容的文本文档

AIML的常用标签:
1:pattern tag:支持模式匹配(正则表达式,模糊匹配),及基于template的返回
2:random tag:支持随机回答(一对多)
4:think,system tag: 支持简单逻辑记忆及自定义函数
5:javascript tag: 支持嵌入js脚本(适用于web chat开发,比如根据情绪改变表情等)。
6:srai tag: 支持多对一回答.
详细内容请参加AIML的官方文档:
http://alicebot.org/TR/2005/WD-aiml/WD-aiml-1.0.1-008.html

chatterbean的例子,需要bsh包。
Alice工厂: AliceBotMother

命令行聊天程序:

需要说明的是:

context.xml:设置application的属性, 及时间格式等可变属性

如上属性,都可以用AIML的<bot>标签及<get>标签访问得到。

splitters.xml:定义什么是句子,即句子的结束符。

substitutions.xml:定义容错规则及特殊字符映射等。

AIML文件:

system标签中的learn方法实现了Alice的学习功能,<input/>标签记住了之前对方的聊天记录, 通过index可以得到(倒序索引)

转自:http://lcllcl987.iteye.com/blog/473256
中文的实现:https://code.google.com/p/ameliebot/ (很久没更新了)

关于JAVA中变量的初始化及类属性的默认值问题

转自:http://hi.baidu.com/yioopayczwgnsye/item/e28120f4ae4a3eee1b111fa9

先看两个例子:
1.VariableInitialization.java

利用JAVAC编译后提示:Variable x may not be initialized.显示在第四行中用到的x可能未被初始化,不可参与运算。

2.ClassAttribute.java

运行结果为:
半径为:0
面积为:0.0
非但没有报错,还给出了可用的运行结果。Circle类中的radius并没有赋初值,但却可以正常使用,而例1里main()方法中的x未赋初值却被告有错。其实问题就在这里,在JAVA中:Local variables must be initialized before they can be used.
而在类定义中的属性若不赋予初值,则JAVA会自动赋予这个属性一个默认值,以下为类的属性的默认值表:

  • 数据类型                        默认值
  • boolean                         false
  • char                           ‘/u0000′(null)
  • 整形(byte,short,int,long)      0
  • 浮点型(float, double)         +0.0f或+0.0d
  • 参考型                           null

总结为一句话便是类里定义的数据成员称为属性,属性可不赋初值,若不赋初值则JAVA会按上表为其添加默认值;方法里定义的数据成员称为变量,变量在参与运算之前必须赋初值。
1.一个变量作为类成员使用的时候,如果没有被初始化,java会为其分配默认值;
2.如果在一个方法中定义一个变量,java不会给其分配默认值,就必须我们来给他初始化,否则将得到编译错误的提示;

Java中使用Runtime和Process类运行外部程序

转自:http://www.cnblogs.com/xxpal/articles/824963.html

使用Runtime.getRuntime().exec()方法可以在java程序里运行外部程序。
1. exec(String command)
2. exec(String command, String envp[], File dir)
3. exec(String cmd, String envp[])
4. exec(String cmdarray[])
5. exec(String cmdarray[], String envp[])
6. exec(String cmdarray[], String envp[], File dir)
一般的应用程序可以直接使用第一版本,当有环境变量传递的时候使用后面的版本。其中2和6版本可以传递一个目录,标识当前目录,因为有些程序是使用相对目录的,所以就要使用这个版本。

cmd.exe /c start <FileName>  (注: 为什么有这句?)

使用DOS命令(比如dir)时也要使用到调用。如果想与调用的程序进行交互,那么就要使用该方法的返回对象Process了,通过Process的getInputStream(),getOutputStream()和getErrorStream()方法可以得到输入输出流,然后通过InputStream可以得到程序对控制台的输出信息,通过OutputStream可以给程序输入指令,这样就达到了程序的交换功能。

用Java编写应用时,有时需要在程序中调用另一个现成的可执行程序或系统命令,这时可以通过组合使用Java提供的Runtime类和Process类的方法实现。下面是一种比较典型的程序模式:

在上面的程序中,第一行的“.\\p.exe”是要执行的程序名,Runtime.getRuntime()返回当前应用程序的Runtime对象,该对象的exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。通过Process可以控制该子进程的执行或获取该子进程的信息。第二条语句的目的等待子进程完成再往下执行。
但在windows平台上,如果处理不当,有时并不能得到预期的结果。下面是笔者在实际编程中总结的几种需要注意的情况:
1、执行DOS的内部命令
如果要执行一条DOS内部命令,有两种方法。一种方法是把命令解释器包含在exec()的参数中。例如,执行dir命令,在NT上,可写成exec(“cmd.exe /c dir”),在windows95/98下,可写成“command.exe /c dir”,其中参数“/c”表示命令执行后关闭DOS立即关闭窗口。另一种方法是,把内部命令放在一个批命令my_dir.bat文件中,在Java程序中写成exec(“my_dir.bat”)。如果仅仅写成exec(“dir”),Java虚拟机则会报运行时错误。前一种方法要保证程序的可移植性,需要在程序中读取运行的操作系统平台,以调用不同的命令解释器。后一种方法则不需要做更多的处理。
2、打开一个不可执行的文件
打开一个不可执行的文件,但该文件存在关联的应用程序,则可以有两种方式。以打开一个word文档a.doc文件为例,Java中可以有以下两种写法:

显然,前一种方法更为简捷方便。
3、执行一个有标准输出的DOS可执行程序
在Windows平台上,运行被调用程序的DOS窗口在程序执行完毕后往往并不会自动关闭,从而导致Java应用程序阻塞在waitfor()语句。导致该现象的一个可能的原因是,该可执行程序的标准输出比较多,而运行窗口的标准输出缓冲区不够大。解决的办法是,利用Java中Process类提供的方法让Java虚拟机截获被调用程序的DOS运行窗口的标准输出,在waitfor()命令之前读出窗口的标准输出缓冲区中的内容。一段典型的程序如下:

 

注:

Java计算器(使用逆波兰表达式算法)

转自:http://space.itpub.net/23071790/viewspace-716661

逆波兰表达式算法实现(Java):

 

深入浅出Swing事件分发线程

转自:http://space.itpub.net/13685345/viewspace-374940

《FilthyRichClients》读书笔记-SwingのEDT

《FilthyRichClients》读完了前几个章节,现将我的体会结合工作以来从事Swing桌面开发的经验,对本书的一些重要概念进行一次分析,对书中的一些遗漏与模糊的地方及时补充,同时使读者消除长期以来“Swing性能低、界面丑陋”诸如此类的旧观念。读书笔记仅谈谈我对Swing的 理解,难免会犯错误,还望广大读者指教。
书中第二章-Swing渲染基本原理 中对Swing的线程做了系统地介绍。相比其他同类Swing教程,已经讲得非常深入了。但是如果读者之前对线程的掌握程度有限,尤其是编写代码比较随意的coder们,动辄就大量编写类似下面这样的代码:

这样的代码可能是netBeans这样的工具生成的“杰作”。但是如果这个人再懒惰一点,可能会直接在TODO下面写上长长一堆代码,还伴随着不可预知的 I/O操作,很多人指责界面被僵住是Swing性能的问题。在新式的JDK中,Swing已经在性能方面改进了很多,完全可以这么说:与应用程序自身的业务计算相比,界面上的耗时可以忽略。但是如果上述恶习改不掉的话,Swing永远“快”不起来,SWT也同样如此,因为它们都是单线程图形工具包。

(注:任何java程序都是由主线程中的main()方法开始执行,当main()方法中的JFrame调用setVisiable(true) 后,引发了另一个线程——事件分派线程,而actionPerformed()方法及paintComponent()方法都是在事件分派Swing线程中被调用,所以如果在actionPerformed()方法中有大量的耗时操作,将会导致用户界面无法响应用户请求,造成用户界面锁死。)

书上有这样一段话:“EventQueue的派发机制由单独的一个线程管理,这个线程称为事件派发线程(EDT)”。和其他很多桌面API一 样,Swing将GUI请求放入一个事件队列中执行。如果不明白什么是事件队列、EDT,它们是如何运作的,那么首先必须澄清四个重要的概念:分别是同步与异步、串行与并行、生产者消费者模式、事件队列。(不同领域串行与并行的含义可能是不同的)
同步与异步:同步是程序在发起请求后开始处理事件并等待处理的结果或等待请求执行完毕,在此之前程序被block住直到请求完成。而异步是当前程序发起请求后立即返回,当前程序不会立即处理该事件并等待处理的结果,请求是在稍后的某一时间才被处理。
串行与并行: 所谓串行是指多个要处理请求顺序执行,处理完一个再处理下一个;并行可以理解为并发,是同时处理多个请求(实际上我们只能理解为是这样,特别是CPU数目少于线程数的机器而言,真正意义的并发是不存在的,各个线程只是断断续续地交替地执行)。下图演示了串行与并行的机制。可以这么说,在引入多线程之前,对于同一进程或者程序而言执行的都是串行操作。
串行:
并行:
生产者/消费者模式:可以想象这样一副场景,某车间的一条传送带,有一个或多个入口不断产生待加工的货物,这种不断产生货物的称为生产者;传送带的末端是一个或多个工人在加工货物,称作消费者。有时由于传送带上没有足够的货物使得某一工人暂时空闲,有时又由于部分货物需加工的时间较长出现传送带上待加工的货物堆积。
如果用Java实现一个简单的生产者消费者模型,利用线程的等待/通知机制很容易实现。给出最基本的同步队列的参考实现

在JDK 5中新出现了许多具有并发性的数据结构在java.util.concurrent包中,它们适合于特殊的场合,本帖不作解释。

事件队列:在计算机数据结构中,队列是一个特殊的数据结构。其一、它是线性的;其二、元素是先进先出的,也就是说进入队列的元素必须从末端进入,先入队的元素先得到执行,后入队的元素等待前面的元素执行完毕出队后才 能执行,队列的处理方式是执行完一个再执行下一个。队列与线程安全是两个不同的概念,如果要将队列加上线程安全的特性,只需要仿照上述生产者/消费者加上 线程的等待/通知即可。
而Swing的事件队列就类似(基本原理相似,但是Swing内部实现会做些优化)于上述的事件队列,说它是单线程图形工具包指的是仅有单一消费者,也就 是常说的事件分发线程(EDT),一般来讲,除非你的应用程序停止,否则EDT会永不间断地徘徊在处理请求与等待请求之间。下图是Swing事件队列的实现机制:

很显然,如果在加工某一个货物上花费很长的时间,那么后续的货物只好等待。对于单一线程的事件队列来说有两个非常突出的特性:一、将同步操作转为异步操作。二、将并行处理转换为串行顺序处理
如果你能理解上述图,那么你就应该意识到:EDT要处理所有GUI操作,它是职责分明且非常忙碌的。也就是说你要记住两条原则:一、职责分明,任何GUI请求都应该在EDT中调用。二、需要处理的GUI请求非常多,包括窗口移动、组件自动重绘、刷新,它很忙,所以任何与GUI无关的处理不要由EDT来负责,尤其是I/O这种耗时的操作。
书中还讲到Swing不是一个“安全线程”的API,为什么要这样设计,再回看上图就会明白:Swing的线程安全不是靠自身组件的API来保 障,虽然repaint方法是这样,但是大多数Swing API是非线程安全的,也就是说不能在任意地方调用,它应该只在EDT中调用。Swing的线程安全靠事件队列和EDT来保障。
invokeLater和invokeAndWait:前文提到,Swing自身不是线程安全,对非EDT的并发调用需通过 invokeLater(runnable)和invokeAndWait(runnable)使请求插入到队列中等待EDT去执行。 invokeLater(runnable)方法是异步的,它会立即返回,具体何时执行请求并不确定,所以命名invokeLater是稍后调用。invokeAndWait(runnable)方法是同步的,它被调用结束会立即block当前线程(调用invokeAndWait的那个线程)直到EDT处理完那个请求。invokeAndWait一般的应用是取得Swing组件的数据,例如取得JSlider组件的当前值:

而外部非EDT线程可以这样调用:

当线程运行到EventQueue.invokeAndWait(task)时会立即被block至少1秒,待invokeAndWait返回时已经可以安全地取到值了。invokeAndWait被这样命名也反映了使用的意图:调用并等待结果。invokeAndWait有非常重要的一条准则是它不能在 EDT中被调用,否则程序会抛出Error,请求也不会去执行。

为什么要有这样一条限制?结合前文不难得出-防止死锁。如果invokeAndWait在EDT中调用,那么首先将请求压进队列,然后EDT便被 block(因为它就是调用invokeAndWait的当前线程)等待请求结束通知它继续运行,而实际上请求将永远得不到执行,因为它在等待队列的调度使EDT执行它,这就陷入一个僵局-EDT等待请求先执行,请求又等待EDT对队列的调度。彼此等待对方释放锁是造成死锁的四类条件之一。Swing有意地避免了这类情况的发生。
书中也提到了同步的绘制请求,作为队列,一条基本原则就是先进先出。那么paintImmediately到底是怎样的呢?显然这个调用请求不会稍后去 执行,也就是说不会插入到队列的末尾等到排在它前面的请求执行完再去执行它,而是“破坏”顺序性原则优先去执行,前面提到,Swing的事件队列相对基础的同步队列做了很多优化,那么这么说它是否被插入到队列最前面呢,也就是0这个位置?貌似也不是,书上说“已经在EDT中调用的方法中间…”,那么就是比当前正在处理的绘制请求还要优先,因为它是当前绘制请求的一部分,所以当前绘制请求(EDT正在处理的那个请求)要等它处理完成后再继续处理。(好好体会吧)
SwingWorker:推荐一篇Blog,http://blog.sina.com.cn/s/blog_4b6047bc010007so.html,作者是原Sun中国工程研究院的陈维雷先生,他对Swing的造诣非浅,他的Blog中有3篇介绍这一主题的文章,详尽程度要比该书详细得多。
最后,谈一下理解EDT对设计模式的帮助。通过上述对事件队列和EDT的分析,有这样一种体会:事件队列是一个非常好的处理并发设计模型,不仅 Swing用它来处理后台,Java的很多地方都在用,只不过对于处理服务器端的并发请求有多个处理线程在等候处理请求,也就是常说的线程池。而对于单用户的桌面应用,单线程调用要比多现成API更简单,“Swing后台这样做是为了保证事件的顺序和可预见性”,而且相对于服务器,客户端桌面层的请求要少得多,所以单线程就足够应对了。
单一Thread化的访问
通过EDT,使得不具备线程安全的Swing函数库避开了并发访问的问题。如果你也有一个不具备thread安全性的函数库并想在multithreaded环境下使用应该怎么办?只要你是从单一的thread来访问这个函数库,程序就不会遭遇到任何数据同步的问题。

java中判断字符串是否为数字

转自:http://www.iteye.com/blog/666544

推荐使用第二个方法,速度最快。

方法一:用JAVA自带的函数

方法二:正则表达式

方法三:

方法四:

方法五:用ascii码

附:判断是否是浮点数

用第三方工具包:

java List.subList

转自:http://blog.csdn.net/sbfivwsll/article/details/7267449

在使用集合中,可能常常需要取集合中的某一部分子集来进行一下操作,于是subList这个方法就映入我们的眼帘,毫不犹豫地使用。
例如以下代码:

代码初步写好后,可能我们想达到的效果是:往集合lists的子集合tempList中添加一个元素6,而原有的集合保持不变。即到达这样的效果:lists = [1, 2, 3, 4],tempList = [3, 4, 6]。但是我们看到实际的结果却是lists里边也添加了元素6。
这是怎么一会事呢,通过查找java原代码我们可以看到:tempList的subList实现代码在AbstractList类里边,然而无论如何,最终的结果都是返回一个AbstractList的子类:SubList(该类是一个使用默认修饰符修饰的类,其源代码位于AbstractList.java类文件里边),
SubList类的构造方法:

里边,将我们原有的list对象给缓存到SubList类对象的一个属性中去了。
而SubList类的add/remove等修改元素的方法中,都使用l进行了操作:

因此,当我们使用子集合tempList进行元素的修改操作时,会影响原有的list集合。所以在使用subList方法时,一定要想清楚,是否需要对子集合进行修改元素而不影响原有的list集合。
如果需要对子集合的元素进行修改操作而不需要影响原集合时,我们可以使用以下方法进行处理: