通用分页算法 |
|
|
一般算法:
int row=200; //记录总数
int page=5;//每页数量
int count=row%5==0?row/page:row/page+1;
非判断的算法:
int row=21;
int pageCount=5;
int sum=(row-1)/pageCount+1;//这样就计算好了页码数量,逢1进1
System.out.println(sum);
|
jquery plugin |
|
|
http://www.jqueryscript.net/
bootstrap: http://www.sharethemes.cn/demo/se7en/timeline.html
|
requestAnimationFrame |
|
|
http://www.zhangxinxu.com/wordpress/2013/09/css3-animation-requestanimationframe-tween-%E5%8A%A8%E7%94%BB%E7%AE%97%E6%B3%95/
http://www.jiawin.com/requestanimationframe-animation-windmill
/* requestAnimationFrame.js
* by zhangxinxu 2013-09-30
*/
(function() {
var lastTime = 0;
var vendors = ['webkit', 'moz'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || // name has changed in Webkit
window[vendors[x] + 'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
var id = window.setTimeout(function() {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}
}());
|
标题截断处理(正则) |
|
|
name.split("[-,;_.—,、((-]")
|
domain regex |
|
|
1、^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}$
2、^([a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,}$
http://www.mkyong.com/regular-expressions/domain-name-regular-expression-example/
描述:
^ #Start of the line
( #Start of group #1
(?! -) #Can't start with a hyphen
[A-Za-z0-9-]{1,63} #Domain name is [A-Za-z0-9-], between 1 and 63 long
(?<!-) #Can't end with hyphen
\\. #Follow by a dot "."
)+ #End of group #1, this group must appear at least 1 time, but allowed multiple times for subdomain
[A-Za-z]{2,6} #TLD is [A-Za-z], between 2 and 6 long
$ #end of the line
|
正则包含等 |
|
|
Regex (Contains Word or not)
Contains: ^.*regexp.*$
Not Contains: ^((?!regexp).)*$
Not contains more words: ^((?!regexp1|regexp2).)*$
Helper links:
http://www.regular-expressions.info/completelines.html
http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#getstarted
http://hugege.com/2008/11/29/regular-expression/
http://regexpal.com/
|
jQuery Marquee Plugin with CSS3 Support |
|
|
http://aamirafridi.com/jquery/jquery-marquee-plugin#examples
https://github.com/aamirafridi/jQuery.Marquee
|
ie6相关问题及处理 |
|
|
1、IE6怪异解析之padding与border算入宽高
原因:未加文档声明造成非盒模型解析
解决方法:加入文档声明<!doctype html>
2、IE6在块元素、左右浮动、设定marin时造成margin双倍(双边距)
解决方法:display:inline
3、以下三种其实是同一种bug,其实也不算是个bug,举个例子:父标签高度20,子标签11,垂直居中,20-11=9,9要分给文字的上面与下面,怎么分?IE6就会与其它的不同,所以,尽量避免。
1)字体大小为奇数之边框高度少1px
解决方法:字体大小设置为偶数或line-height为偶数
2)line-height,文本垂直居中差1px
解决方法:padding-top代替line-height居中,或line-height加1或减1
3)与父标签的宽度的奇偶不同的居中造成1px的偏离
解决方法:如果父标签是奇数宽度,则子标签也用奇数宽度;如果是父标签偶数宽度,则子标签也用偶数宽度
4、内部盒模型超出父级时,父级被撑大
解决方法:父标签使用overflow:hidden
5、line-height默认行高bug
解决方法:line-height设值
6、行标签之间会有一小段空白
解决方法:float或结构并排(可读性差,不建议)
7、标签高度无法小于19px
解决方法:overflow: hidden;
8、左浮元素margin-bottom失效
解决方法:显示设置高度 or 父标签设置_padding-bottom代替子标签的margin-bottom or 再放个标签让父标签浮动,子标签
margin- bottom,即(margin-bottom与float不同时作用于一个标签)
9、img于块元素中,底边多出空白
解决方法:父级设置overflow: hidden; 或 img { display: block; } 或 _margin: -5px;
10、li之间会有间距
解决方法:float: left;
11、块元素中有文字及右浮动的行元素,行元素换行
解决方法:将行元素置于块元素内的文字前
12、position下的left,bottom错位
解决方法:为父级(relative层)设置宽高或添加*zoom:1
13、子级中有设置position,则父级overflow失效
解决方法:为父级设置position:relative
以下是补充:上面要先看
1、终极方法:条件注释
<!--[if lte IE 6]> 这段文字仅显示在 IE6及IE6以下版本。 <![endif]-->
<!--[if gte IE 6]> 这段文字仅显示在 IE6及IE6以上版本。 <![endif]-->
<!--[if gt IE 6]> 这段文字仅显示在 IE6以上版本(不包含IE6)。 <![endif]-->
<!--[if IE 5.5]> 这段文字仅显示在 IE5.5。 <![endif]-->
<!--在 IE6及IE6以下版本中加载css-->
<!--[if lte IE 6]> <link type="text/css" rel="stylesheet" href="css/ie6.css" mce_href="css/ie6.css" /><![endif]-->
缺点是在IE浏览器下可能会增加额外的HTTP请求数。
2、CSS选择器区分
IE6不支持子选择器;先针对IE6使用常规申明CSS选择器,然后再用子选择器针对IE7+及其他浏览器。
复制代码
代码如下:
/* IE6 专用 */
.content {color:red;}
/* 其他浏览器 */
div>p .content {color:blue;} -->
3、PNG半透明图片的问题
虽然可以通过JS等方式解决,但依然存在载入速度等问题,所以,这个在设计上能避免还是尽量避免为好。以达到网站最大优化。
4、IE6下的圆角
IE6不支持CSS3的圆角属性,性价比最高的解决方法就是用图片圆角来替代,或者放弃IE6的圆角。
5、IE6背景闪烁
如果你给链接、按钮用CSS sprites作为背景,你可能会发现在IE6下会有背景图闪烁的现象。造成这个的原因是由于IE6没有将背景图缓存,每次触发hover的时候都会重新加载,可以用JavaScript设置IE6缓存这些图片:
复制代码
代码如下:
document.execCommand("BackgroundImageCache",false,true);
6、最小高度
IE6 不支持min-height属性,但它却认为height就是最小高度。解决方法:使用ie6不支持但其余浏览器支持的属性!important。
复制代码
代码如下:
#container {min-height:200px; height:auto !important; height:200px;}
7、最大高度
复制代码
代码如下:
//直接使用ID来改变元素的最大高度
var container = document.getElementById('container');
container.style.height = (container.scrollHeight > 199) ? "200px" : "auto";
//写成函数来运行
function setMaxHeight(elementId, height){
var container = document.getElementById(elementId);
container.style.height = (container.scrollHeight > (height - 1)) ? height + "px" : "auto";
}
//函数示例
setMaxHeight('container1', 200);
setMaxHeight('container2', 500);
8、100% 高度
在IE6下,如果要给元素定义100%高度,必须要明确定义它的父级元素的高度,如果你需要给元素定义满屏的高度,就得先给html和body定义height:100%;。
9、最小宽度
同max-height和max-width一样,IE6也不支持min-width。
复制代码
代码如下:
//直接使用ID来改变元素的最小宽度
var container = document.getElementById('container');
container.style.width = (container.clientWidth < width) ? "500px" : "auto";
//写成函数来运行
function setMinWidth(elementId, width){
var container = document.getElementById(elementId);
container.style.width = (container.clientWidth < width) ? width + "px" : "auto";
}
//函数示例
setMinWidth('container1', 200);
setMinWidth('container2', 500);
10、最大宽度
复制代码
代码如下:
//直接使用ID来改变元素的最大宽度
var container = document.getElementById(elementId);
container.style.width = (container.clientWidth > (width - 1)) ? width + "px" : "auto";
//写成函数来运行
function setMaxWidth(elementId, width){
var container = document.getElementById(elementId);
container.style.width = (container.clientWidth > (width - 1)) ? width + "px" : "auto";
}
//函数示例
setMaxWidth('container1', 200);
setMaxWidth('container2', 500);
11、双边距Bug
当元素浮动时,IE6会错误的把浮动方向的margin值双倍计算。个人觉得较好解决方法是避免float和margin同时使用。
12、清除浮动
如果你想用div(或其他容器)包裹一个浮动的元素,你会发现必须给div(容器)定义明确的height、width、overflow之中一个属性(除了auto值)才能将浮动元素严实地包裹。
复制代码
代码如下:
#container {border:1px solid #333; overflow:auto; height:100%;}
#floated1 {float:left; height:300px; width:200px; background:#00F;}
#floated2 {float:right; height:400px; width:200px; background:#F0F;}
更多:http://www.twinsenliang.net/skill/20090413.html
13、浮动层错位
当内容超出外包容器定义的宽度时,在IE6中容器会忽视定义的width值,宽度会错误地随内容宽度增长而增长。
浮动层错位问题在IE6下没有真正让人满意的解决方法,虽然可以使用overflow:hidden;或overflow:scroll;来修正, 但hidden容易导致其他一些问题,scroll会破坏设计;JavaScript也没法很好地解决这个问题。所以建议是一定要在布局上避免这个问题发 生,使用一个固定的布局或者控制好内容的宽度(给内层加width)。
14、躲猫猫bug
在IE6和IE7下,躲猫猫bug是一个非常恼人的问题。一个撑破了容器的浮动元素,如果在他之后有不浮动的内容,并且有一些定义了:hover的链接,当鼠标移到那些链接上时,在IE6下就会触发躲猫猫。
解决方法很简单:
1.在(那个未浮动的)内容之后添加一个<span style="clear: both;"> </span>
2.触发包含了这些链接的容器的hasLayout,一个简单的方法就是给其定义height:1%;
15、绝对定位元素的1像素间距bug
IE6下的这个错误是由于进位处理误差造成(IE7已修复),当绝对定位元素的父元素高或宽为奇数时,bottom和right会产生错误。唯一的解决办法就是给父元素定义明确的高宽值,但对于液态布局没有完美的解决方法。
16、3像素间距bug
在IE6中,当文本(或无浮动元素)跟在一个浮动的元素之后,文本和这个浮动元素之间会多出3像素的间隔。
给浮动层添加 display:inline 和 -3px 负值margin
给中间的内容层定义 margin-right 以纠正-3px
17、IE下z-index的bug
在IE浏览器中,定位元素的z-index层级是相对于各自的父级容器,所以会导致z-index出现错误的表现。解决方法是给其父级元素定义z-index,有些情况下还需要定义position:relative。
18、Overflow Bug
在IE6/7中,overflow无法正确的隐藏有相对定位position:relative;的子元素。解决方法就是给外包容器.wrap加上position:relative;。
19、横向列表宽度bug
如果你使用float:left;把<li>横向摆列,并且<li>内包含的<a>(或其他)触发了 hasLayout,在IE6下就会有错误的表现。解决方法很简单,只需要给<a>定义同样的float:left;即可。
20、列表阶梯bug
列表阶梯bug通常会在给<li>的子元素<a>使用float:left;时触发,我们本意是要做一个横向的列表(通常 是导航栏),但IE却可能呈现出垂直的或者阶梯状。解决办法就是给<li>定义float:left;而非子元素<a>,或者 给<li>定义display:inline;也可以解决。
21、垂直列表间隙bug
当我们使用<li> 包含一个块级子元素时,IE6(IE7也有可能)会错误地给每条列表元素(<li>)之间添加空隙。
解决方法:把<a>flaot并且清除float来解决这个问题;另外一个办法就是触发<a>的hasLayout(如定 义高宽、使用zoom:1;);也可以给<li> 定义display:inline;来解决此问题;另外还有一个极有趣的方法,给包含的文本末尾添加一个空格。
22、IE6中的:hover
在IE6中,除了(需要有href属性)才能触发:hover行为,这妨碍了我们实现许多鼠标触碰效果,但还是有一些法子是可以解决它的。最好是不要用:hover来实现重要的功能,仅仅只用它来强化效果。
23、IE6调整窗口大小的 Bug
当把body居中放置,改变IE浏览器大小的时候,任何在body里面的相对定位元素都会固定不动了。解决办法:给body定义position:relative;就行了。
24、文本重复Bug
在IE6中,一些隐藏的元素(如注释、display:none;的元素)被包含在一个浮动元素里,就有可能引发文本重复bug。解决办法:给浮动元素添加display:inline;。
http://www.jb51.net/css/76894.html
|
盒子模型 |
|
|
ie 盒子模型的范围也包括 margin、border、padding、content,和标准 w3c 盒子模型不同的是:ie 盒子模型的 content 部分包含了 border 和 pading。
例:一个盒子的 margin 为 20px,border 为 1px,padding 为 10px,content 的宽为 200px、高为 50px,假如用标准 w3c 盒子模型解释,那么这个盒子需要占据的位置为:宽 20*2+1*2+10*2+200=262px、高 20*2+1*2*10*2+50=112px,盒子的实际大小为:宽 1*2+10*2+200=222px、高 1*2+10*2+50=72px;假如用ie 盒子模型,那么这个盒子需要占据的位置为:宽 20*2+200=240px、高 20*2+50=70px,盒子的实际大小为:宽 200px、高 50px。
那应该选择哪中盒子模型呢?当然是“标准 w3c 盒子模型”了。怎么样才算是选择了“标准 w3c 盒子模型”呢?很简单,就是在网页的顶部加上 doctype 声明。假如不加 doctype 声明,那么各个浏览器会根据自己的行为去理解网页,即 ie 浏览器会采用 ie 盒子模型去解释你的盒子,而 ff 会采用标准 w3c 盒子模型解释你的盒子,所以网页在不同的浏览器中就显示的不一样了。反之,假如加上了 doctype 声明,那么所有浏览器都会采用标准 w3c 盒子模型去解释你的盒子,网页就能在各个浏览器中显示一致了。
再用 jquery 做的例子来证实一下。
代码1:
<html>
<head>
<title>你用的盒子模型是?</title>
<script language="javascript" src="jquery.min.js"></script>
<script language="javascript">
var sbox = $.boxmodel ? "标准w3c":"ie";
document.write("您的页面目前支持:"+sbox+"盒子模型");
</script>
</head>
<body>
</body>
</html>
上面的代码没有加上 doctype 声明,在 ie 浏览器中显示“ie盒子模型”,在 ff 浏览器中显示“标准 w3c 盒子模型”。
代码2:
<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html>
<head>
<title>你用的盒子模型是标准w3c盒子模型</title>
<script language="javascript" src="jquery.min.js"></script>
<script language="javascript">
var sbox = $.boxmodel ? "标准w3c":"ie";
document.write("您的页面目前支持:"+sbox+"盒子模型");
</script>
</head>
<body>
</body>
</html>
代码2 与代码1 唯一的不同的就是顶部加了 doctype 声明。在所有浏览器中都显示“标准 w3c 盒子模型”。
所以为了让网页能兼容各个浏览器,让我们用标准 w3c 盒子模型。
http://www.cnblogs.com/cchyao/archive/2010/07/12/1775846.html
|
js 闭包 |
|
|
闭包的简单概念:闭包就是能够读取其他函数内部变量的函数。
函数内部的函数闭包的两个最大的作用:
1、读取函数内部的变量
2、变量的值始终保持在内存中
function A()
{
var n=999;
nAdd=function(){
n+=1
}
function B(){
alert(n);
}
return B;
}
var result=A();
result(); // 999
nAdd();
result(); // 1000
|
js 倒计时 |
|
|
/**
* 倒计时通用设置
*/
function countdown(target, date, func) {
var temp = target.countdown({
hourText: ':',
minText: ':',
secText: '',
hourSingularText: ':',
minSingularText: ':',
secSingularText: '',
leadingZero: true,
date: date,
template: '%i %s',
onComplete: function(event) {
func.call();
}
});
return temp;
}
https://github.com/tomgrohl/jCountdown/
|
js 数字效果 |
|
|
function commaSeparateNumber(val) {
while (/(\d+)(\d{3})/.test(val.toString())){
val = val.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
}
return val;
}
function magic_number(target, value) {
target.animate({count: value}, {
duration: 500,
easing: 'swing',
step: function() {
target.text(commaSeparateNumber(parseInt(this.count))); // String(parseInt(this.count))
}
});
};
function magic_rationumber(target, value) {
target.animate({count: value}, {
duration: 3000,
easing: 'easeOutCubic',
step: function() {
target.text(parseInt(this.count) + '%'); // String(parseInt(this.count))
}
});
};
setInterval(function() {
magic_number($('#wetRequest'), Math.random() * 1000000000);
magic_number($('#webClick'), Math.random() * 1000000000);
magic_rationumber($('#webClickRatio'), Math.random() * 100);
}, 5000);
|
js 文本选择 |
|
|
var userSelection, text;
if (window.getSelection) {
//现代浏览器
userSelection = window.getSelection();
} else if (document.selection) {
//IE浏览器 考虑到Opera,应该放在后面
userSelection = document.selection.createRange();
}
if (!(text = userSelection.text)) {
text = userSelection;
}
http://www.zhangxinxu.com/wordpress/?p=1591
|
JS表格排序 |
|
|
appendChild:1、先把元素从原有的父级上删掉。2、添加到新的父级。
排序的原理:从一堆数里找出一个最小的数用appendChild插入到最后,再在剩下的数里找最小的数用appendChild插入到最后,如此重复就能找把所有的数实现排序。
表格排序思路:
1、获取元素。
2、创建一个空数组 var arr=[];
3、用for循环把表格的每行数赋值给数组 arr[i]=oTable.tBodies[0].rows[i];
4、用sort()把数组里面的元素进行排序。
5、用for循环把数组里排好序的数用appendChild插入到tBodies。
完整代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>排序</title>
<script>
window.onload=function()
{
var oBtn=document.getElementById('btn');
var oTable=document.getElementById('table');
oBtn.onclick=function()
{
var arr=[];
for(var i=0;i<oTable.tBodies[0].rows.length;i++)
{
arr[i]=oTable.tBodies[0].rows[i];
};
arr.sort(function(tr1,tr2){
n1=parseInt(tr1.cells[0].innerHTML);
n2=parseInt(tr2.cells[0].innerHTML);
return n1-n2;
});
for(var i=0;i<arr.length;i++)
{
oTable.tBodies[0].appendChild(arr[i]);
};
};
};
</script>
</head>
<body>
<input type="button" value="排序" id="btn" />
<table id="table" border="1" width="100%" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>专业</th>
</tr>
</thead>
<tbody>
<tr>
<td>58</td>
<td>Simon</td>
<td>网站设计</td>
</tr>
<tr>
<td>20</td>
<td>Melon</td>
<td>网站设计</td>
</tr>
<tr>
<td>98</td>
<td>张三</td>
<td>物流</td>
</tr>
<tr>
<td>87</td>
<td>李四三</td>
<td>物流</td>
</tr>
<tr>
<td>798</td>
<td>张三</td>
<td>物流</td>
</tr>
</tbody>
</table>
</body>
</html>
|
java 图片 尺寸 |
|
|
File file = new File("C:\\Koala.jpg");
BufferedImage bi = ImageIO.read(file);int width = bi.getWidth();int height = bi.getHeight();
这种方式代码很简单,但是效率是很差的,ImageIO将图片文件读入内存,以便进行更多的操作。java中还有ImageReader这个类,使用这个类避免将图片全部解码,这里是官方的文档说明。 要使用这个类,也需要ImageIO这个类得到ImageReader的迭代器,支持多种获取的方式,然后将图像文件设置为ImageReader的输入源。就可以通过ImageReader来获取图片的长宽信息了。
//通过文件的类型获取
Iterator readers = ImageIO.getImageReadersByFormatName("jpg");
//通过文件的后缀获取
Iterator readers = ImageIO.getImageReadersBySuffix("jpg");
ImageReader reader = readers.next();
File file = new File("C:\\Koala.jpg");
ImageInputStream input = ImageIO.createImageInputStream(file);
reader.setInput(input, true);
int width = reader.getWidth(0);
int height = reader.getHeight(0);
|
select2 搜索 中文乱码 |
|
|
js: data: function (params) {
return {
input: encodeURI(decodeURIComponent(params.term, true)), // search term
type: '${type!""}'
};
},
java :input = java.net.URLDecoder.decode(new String(input.getBytes("ISO-8859-1" ),"UTF-8") , "UTF-8");
|
list 删除 |
|
|
for (Iterator<PosConf> it = list.iterator(); it.hasNext();) {
PosConf posConf = it.next();
if ("all".equals(posConf.getPosId()))
it.remove();
}
|
js string format |
|
|
var JQUERY4U = {};
JQUERY4U.UTIL = {
formatVarString: function() {
var args = [].slice.call(arguments);
if(this.toString() != '[object Object]') {
args.unshift(this.toString());
}
var pattern = new RegExp('{([1-' + args.length + '])}','g');
return String(args[0]).replace(pattern, function(match, index) { return args[index]; });
}
}
//JQUERY4U.UTIL.formatVarString('{1} is a {2} aimed to help you learn {3}.', 'jQuery4u', 'blog', 'jQuery')
String.format = function() {
if (arguments.length == 0)
return null;
var str = arguments[0];
for ( var i = 1; i < arguments.length; i++) {
var re = new RegExp('\\{' + (i - 1) + '\\}', 'gm');
str = str.replace(re, arguments[i]);
}
return str;
};
//String.format('{0} is a {1} aimed to help you learn {2}.', 'jQuery4u', 'blog', 'jQuery')
|
htmlparser.jar |
|
|
Parser parser = new Parser();
parser.setURL(xx.getGoodsUrl());
NodeFilter filter = new AndFilter(new TagNameFilter("dt"), new HasAttributeFilter("class", "subTit"));
NodeList list = parser.parse(filter);
if (list.size() == 1) {
String des = list.elementAt(0).toPlainTextString();
logger.info(xx.getAdid() + ":" + des);
if (!StringUtils.isBlank(des)) {
xx.setDescript(des);
}
}
|
jQuery accordion hack |
|
|
// hack
$('#accordion h3').attr('class', 'ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-accordion-icons').off('click').click(function() {
if($(this).next().is(':hidden')) {
$(this).find('span').attr('class', 'ui-accordion-header-icon ui-icon ui-icon-triangle-1-s');
} else {
$(this).find('span').attr('class', 'ui-accordion-header-icon ui-icon ui-icon-triangle-1-e');
}
$(this).next().toggle('fast');
});
|
JSON数组排序 |
|
|
JSONArray valueArray = JSONArray.parseArray("json array str");
ComparatorChain compChain = new ComparatorChain();
Comparator comp = ComparableComparator.getInstance();
comp = ComparatorUtils.reversedComparator(comp); // 降序排, 不调用则升序排
compChain.addComparator(new BeanComparator("count", comp));
Collections.sort(valueArray, compChain);
|
Calendar 类 format线程安全问题 |
|
|
http://bijian1013.iteye.com/blog/1873336
解决SimpleDateFormat的线程不安全问题的方法
博客分类: java多线程
javathreadSimpleDateFormat线程安全
在Java项目中,我们通常会自己写一个DateUtil类,处理日期和字符串的转换,如下所示:
Java代码 收藏代码
public class DateUtil01 {
private SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public void format(Date date) {
System.out.println(dateformat.format(date));
}
public void parse(String str) {
try {
System.out.println(dateformat.parse(str));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
然而,由于SimpleDateFormat类不是线程安全的,所以在多线程的环境下,往往会出现意想不到的结果。
如下是我写的测试其是否存在安全问题的实例:
1.日期工具处理类的接口
Java代码 收藏代码
package com.bijian.study.date;
import java.util.Date;
public interface DateUtilInterface {
public void format(Date date);
public void parse(String str);
}
2.日期工具实现类
Java代码 收藏代码
package com.bijian.study.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil01 implements DateUtilInterface {
private SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void format(Date date) {
System.out.println(dateformat.format(date));
}
@Override
public void parse(String str) {
try {
System.out.println(dateformat.parse(str));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
3.调用日期工具的线程类
Java代码 收藏代码
package com.bijian.study.date;
import java.util.Calendar;
import java.util.Date;
public class DateThread implements Runnable {
DateUtilInterface dateUtil = null;
public DateThread(DateUtilInterface dateUtil) {
this.dateUtil = dateUtil;
}
public void run() {
int year = 2000;
Calendar cal;
for (int i = 1; i < 100; i++) {
System.out.println("no." + i);
year++;
cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
//Date date = cal.getTime();
//dateUtil.format(date);
dateUtil.parse(year + "-05-25 11:21:21");
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
4.测试主方法
Java代码 收藏代码
package com.bijian.study.date;
public class DateMainTest {
public static void main(String[] args) {
DateUtilInterface dateUtil = new DateUtil01();
Runnable runabble = new DateThread(dateUtil);
for(int i=0;i<10;i++){
new Thread(runabble).start();
}
}
}
运行结果:
Text代码 收藏代码
no.1
no.1
no.1
Fri May 25 11:21:21 CST 2001
Fri May 25 11:21:21 CST 2001
Fri May 25 11:21:21 CST 2001
no.1
no.1
Fri May 25 11:21:21 CST 2001
Fri May 25 11:21:21 CST 2001
no.1
no.1
Fri May 25 11:21:21 CST 2001
no.1
Fri May 25 11:21:21 CST 2001
no.1
Fri May 25 11:00:21 CST 2001
Wed Sep 25 11:21:21 CST 2002
no.1
no.2
no.2
Sat May 25 11:21:21 CST 2002
no.2
no.2
no.2
Sat May 25 11:21:21 CST 2002
no.2
Sat May 25 11:21:21 CST 2002
Fri May 25 11:21:21 CST 2001
Sat May 25 11:21:21 CST 2002
no.2
Sat May 25 11:21:21 CST 2002
no.2
Sat May 25 11:21:21 CST 2002
no.2
Sat May 25 11:21:21 CST 2002
Exception in thread "Thread-2" java.lang.NumberFormatException: For input string: ".00221E.00221E4"
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at java.lang.Double.parseDouble(Unknown Source)
at java.text.DigitList.getDouble(Unknown Source)
at java.text.DecimalFormat.parse(Unknown Source)
at java.text.SimpleDateFormat.subParse(Unknown Source)
at java.text.SimpleDateFormat.parse(Unknown Source)
at java.text.DateFormat.parse(Unknown Source)
at com.bijian.study.date.DateUtil01.parse(DateUtil01.java:19)
at com.bijian.study.date.DateThread.run(DateThread.java:24)
at java.lang.Thread.run(Unknown Source)
Exception in thread "Thread-5" java.lang.NumberFormatException: For input string: ".00221E.00221E44"
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at java.lang.Double.parseDouble(Unknown Source)
at java.text.DigitList.getDouble(Unknown Source)
at java.text.DecimalFormat.parse(Unknown Source)
at java.text.SimpleDateFormat.subParse(Unknown Source)
at java.text.SimpleDateFormat.parse(Unknown Source)
at java.text.DateFormat.parse(Unknown Source)
at com.bijian.study.date.DateUtil01.parse(DateUtil01.java:19)
at com.bijian.study.date.DateThread.run(DateThread.java:24)
at java.lang.Thread.run(Unknown Source)
no.3
no.3
Sun May 25 11:21:21 CST 2003
no.3
no.3
no.3
Sun May 25 11:21:21 CST 2003
no.4
Sun May 25 11:21:21 CST 2003
no.3
Tue May 25 11:21:21 CST 2004
no.2
Sun May 25 11:21:21 CST 2003
no.3
Thu Jan 01 00:21:21 CST 1970
Exception in thread "Thread-7" Exception in thread "Thread-0" java.lang.NumberFormatException: For input string: "E212"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at java.text.DigitList.getLong(Unknown Source)
at java.text.DecimalFormat.parse(Unknown Source)
at java.text.SimpleDateFormat.subParse(Unknown Source)
at java.text.SimpleDateFormat.parse(Unknown Source)
at java.text.DateFormat.parse(Unknown Source)
at com.bijian.study.date.DateUtil01.parse(DateUtil01.java:19)
at com.bijian.study.date.DateThread.run(DateThread.java:24)
at java.lang.Thread.run(Unknown Source)
java.lang.NumberFormatException: For input string: "E212"
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at java.lang.Double.parseDouble(Unknown Source)
at java.text.DigitList.getDouble(Unknown Source)
at java.text.DecimalFormat.parse(Unknown Source)
at java.text.SimpleDateFormat.subParse(Unknown Source)
at java.text.SimpleDateFormat.parse(Unknown Source)
at java.text.DateFormat.parse(Unknown Source)
at com.bijian.study.date.DateUtil01.parse(DateUtil01.java:19)
at com.bijian.study.date.DateThread.run(DateThread.java:24)
at java.lang.Thread.run(Unknown Source)
Exception in thread "Thread-8" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at java.text.DigitList.getLong(Unknown Source)
at java.text.DecimalFormat.parse(Unknown Source)
at java.text.SimpleDateFormat.subParse(Unknown Source)
at java.text.SimpleDateFormat.parse(Unknown Source)
at java.text.DateFormat.parse(Unknown Source)
at com.bijian.study.date.DateUtil01.parse(DateUtil01.java:19)
at com.bijian.study.date.DateThread.run(DateThread.java:24)
at java.lang.Thread.run(Unknown Source)
no.4
no.4
...
...
...
从如上运行结果来看,SimpleDateFormat的parse方法有线程安全问题。
修改调用日期工具的线程类如下,测试SimpleDateFormat的format方法是否有线程安全问题:
Java代码 收藏代码
package com.bijian.study.date;
import java.util.Calendar;
import java.util.Date;
public class DateThread implements Runnable {
DateUtilInterface dateUtil = null;
public DateThread(DateUtilInterface dateUtil) {
this.dateUtil = dateUtil;
}
public void run() {
int year = 2000;
Calendar cal;
for (int i = 1; i < 100; i++) {
System.out.println("no." + i);
year++;
cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
Date date = cal.getTime();
dateUtil.format(date);
//dateUtil.parse(year + "-05-25 11:21:21");
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
运行结果:
Text代码 收藏代码
no.1
no.1
2001-05-22 13:07:22
2001-05-22 13:07:22
no.1
no.1
2001-05-22 13:07:22
2001-05-22 13:07:22
no.1
2001-05-22 13:07:22
no.1
no.1
2001-05-22 13:07:22
2001-05-22 13:07:22
no.1
no.1
2001-05-22 13:07:22
2001-05-22 13:07:22
no.1
2001-05-22 13:07:22
no.2
no.2
no.2
no.2
2002-05-22 13:07:22
no.2
2002-05-22 13:07:22
2002-05-22 13:07:22
no.2
2002-05-22 13:07:22
no.2
...
...
...
多次运行,均未出现异常,因此个人预测,SimpleDateFormat的format方法没有线程安全的问题。
有三种方法可以解决以上安全问题。
1).使用同步
Java代码 收藏代码
package com.bijian.study.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil02 implements DateUtilInterface {
private SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void format(Date date) {
System.out.println(dateformat.format(date));
}
@Override
public void parse(String str) {
try {
synchronized(dateformat){
System.out.println(dateformat.parse(str));
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
修改DateMainTest.java的DateUtilInterface dateUtil = new DateUtil01();为DateUtilInterface dateUtil = new DateUtil02();测试OK。
不过,当线程较多时,当一个线程调用该方法时,其他想要调用此方法的线程就要block,这样的操作也会一定程度上影响性能。
2).每次使用时,都创建一个新的SimpleDateFormat实例
Java代码 收藏代码
package com.bijian.study.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil03 implements DateUtilInterface {
@Override
public void format(Date date) {
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(dateformat.format(date));
}
@Override
public void parse(String str) {
try {
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(dateformat.parse(str));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
修改DateMainTest.java的DateUtilInterface dateUtil = new DateUtil02();为DateUtilInterface dateUtil = new DateUtil03();测试OK。
3).借助ThreadLocal对象每个线程只创建一个实例
借助ThreadLocal对象每个线程只创建一个实例,这是推荐的方法
对于每个线程SimpleDateFormat不存在影响他们之间协作的状态,为每个线程创建一个SimpleDateFormat变量的拷贝或者叫做副本,代码如下:
Java代码 收藏代码
package com.bijian.study.date;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil04 implements DateUtilInterface {
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
// 第一次调用get将返回null
private static ThreadLocal threadLocal = new ThreadLocal(){
protected Object initialValue() {
return null;//直接返回null
}
};
// 获取线程的变量副本,如果不覆盖initialValue,第一次get返回null,故需要初始化一个SimpleDateFormat,并set到threadLocal中
public static DateFormat getDateFormat() {
DateFormat df = (DateFormat) threadLocal.get();
if (df == null) {
df = new SimpleDateFormat(DATE_FORMAT);
threadLocal.set(df);
}
return df;
}
@Override
public void parse(String textDate) {
try {
System.out.println(getDateFormat().parse(textDate));
} catch (ParseException e) {
e.printStackTrace();
}
}
@Override
public void format(Date date) {
System.out.println(getDateFormat().format(date));
}
}
创建一个ThreadLocal类变量,这里创建时用了一个匿名类,覆盖了initialValue方法,主要作用是创建时初始化实例。
也可以采用下面方式创建。
Java代码 收藏代码
package com.bijian.study.date;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil05 implements DateUtilInterface {
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
@SuppressWarnings("rawtypes")
private static ThreadLocal threadLocal = new ThreadLocal() {
protected synchronized Object initialValue() {
return new SimpleDateFormat(DATE_FORMAT);
}
};
public DateFormat getDateFormat() {
return (DateFormat) threadLocal.get();
}
@Override
public void parse(String textDate) {
try {
System.out.println(getDateFormat().parse(textDate));
} catch (ParseException e) {
e.printStackTrace();
}
}
@Override
public void format(Date date) {
System.out.println(getDateFormat().format(date));
}
}
修改DateMainTest.java的DateUtilInterface dateUtil = new DateUtil03();为DateUtilInterface dateUtil = new DateUtil04();或者DateUtilInterface dateUtil = new DateUtil05();测试OK。
最后,当然也可以使用apache commons-lang包的DateFormatUtils或者FastDateFormat实现,apache保证是线程安全的,并且更高效。
附:Oracle官方bug说明: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6178997
|
强制不缓存 |
|
|
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
// new
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Expires" content="Fri, 30 Apr 2010 11:12:01 GMT" />
<meta http-equiv="Expires" content="0" />
<HTTP-EQUIV="PRAGMA" CONTENT="NO-STORE" />
|
sring util |
|
|
public static final String regex = "(http:|https:)//[^[A-Za-z0-9\\._\\?%&+\\-=/#]]*";
public static String extractBefore(String source, String identifier) {
if (StringUtils.isBlank(source)) {
return "";
}
int index = source.indexOf(identifier);
if (index != -1) {
return source.substring(0, index);
}
return source;
}
public static String getArrayString(String[] ss, String mark) {
StringBuffer buffer = new StringBuffer();
if (ss != null && ss.length > 0) {
for (int i = 0; i < ss.length; i++) {
if (i > 0)
buffer.append(",");
buffer.append(mark + ss[i] + mark);
}
}
return buffer.toString();
}
public static String getArrayString(List<String> list, String mark) {
StringBuffer buffer = new StringBuffer();
if (list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
if (i > 0)
buffer.append(",");
buffer.append(mark + list.get(i) + mark);
}
}
return buffer.toString();
}
public static String getMsgHighLight(String message, String keyword) {
if (StringUtils.isBlank(keyword)) {
return message;
}
Pattern p = Pattern.compile(keyword, Pattern.CASE_INSENSITIVE);
Matcher matcher = p.matcher(message);
StringBuffer sb = new StringBuffer();
boolean flag = false;
while (matcher.find()) {
flag = true;
matcher.appendReplacement(sb, String.format("<msg>%s</msg>", matcher.group()));
}
matcher.appendTail(sb);
if (!flag) {
return message;
}
return sb.toString();
}
public static String getMsgLinkTrue(String message) {
if (StringUtils.isBlank(message)) {
return message;
}
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(message);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String urlStr = matcher.group();
StringBuffer replace = new StringBuffer();
replace.append("<a href=\"").append(urlStr);
replace.append("\" target=\"_blank\">" + urlStr + "</a>");
matcher.appendReplacement(sb, replace.toString());
}
matcher.appendTail(sb);
return sb.toString();
}
|
spring mvc 多个文件 |
|
|
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();
file.getOriginalFilename());
}
|
mybatis cache |
|
|
http://www.iteye.com/topic/1112327
|
js string format |
|
|
String.prototype.format = function() {
var args = arguments;
return this.replace(/{(\d+)}/g, function(match, i) {
return typeof args[i] != 'undefined' ? args[i] : match;
});
};
String.format = function(template) {
if (0 == arguments.length)
return null;
var args = Array.prototype.slice.call(arguments, 1);
return String.prototype.format.apply(template, args);
}
if (typeof jQuery != 'undefined') {
jQuery.extend({
format : function(template) {
return String.format.apply(template, arguments);
}
});
}
// console.log('{0} {1}'.format('hello', 'world'));
// console.log(String.format('{0} {1}', 'hello', 'world'));
// console.log($.format('{0} {1}', 'hello', 'jQuery'));
|
简单按中文拼音排序 |
|
|
/**
* 中文字符排序
*
* @date 2015年5月6日
* @author hzcuijie@corp.netease.com
*/
class SortChineseName implements Comparator<AdIndustryInfo> {
Collator cmp = Collator.getInstance(java.util.Locale.CHINA);
@Override
public int compare(AdIndustryInfo o1, AdIndustryInfo o2) {
if (cmp.compare(o1.getCategory(), o2.getCategory()) > 0) {
return 1;
} else if (cmp.compare(o1.getCategory(), o2.getCategory()) < 0) {
return -1;
}
return 0;
}
}
|
Linux java 执行 python |
|
|
//exec(String[] cmd) - cmd[0]:path of python-3.x cmd[1]:path of your python code cmd[2],[3]:arguments
//if you only invoke python code without arguments, `Process p = r.exec("python path-of-your-code");` instead.
public static void main(String[] args) {
try {
Runtime r = Runtime.getRuntime();
// String[] cmd = { "/usr/bin/python", "/styx/home/hzcuijie/ConceptNetSimilarity.py", "cat", "dog" };
String[] cmd = { "cmd", "/c", "D:\\ConceptNetSimilarity.py", "cat", "dog" };
Process p = r.exec(cmd); //"cmd /c D:\\ConceptNetSimilarity.py cat dog"
p.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = br.readLine()) != null) {
System.out.println(line);
}
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
|
Linux 生成图片文字乱码问题 |
|
|
File f = new File(fontFile);
logger.info("file content..." + f.getAbsoluteFile());
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, f));
在应用启动时设置
|