魔豆的BLOG

一个程序员的学习足迹...

  博客园 :: 首页 :: 联系 :: 订阅 订阅 :: 管理
  10 Posts :: 305 Stories :: 83 Comments :: 10 Trackbacks

公告

2012年5月25日 #

一般大家都知道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时的查询速度,看下面的程序:

package com.mangocity.test;    
import java.util.LinkedList;    
import java.util.List;    
import java.util.Random;    
import java.util.ArrayList;    
import java.util.Arrays;    
import java.util.Collections;    
public class TestList ...{    
     public static final int N=50000;    
   
     public static List values;    
   
     static...{    
         Integer vals[]=new Integer[N];    
   
         Random r=new Random();    
   
         for(int i=0,currval=0;i<N;i++)...{    
             vals=new Integer(currval);    
             currval+=r.nextInt(100)+1;    
         }    
   
         values=Arrays.asList(vals);    
     }    
   
     static long timeList(List lst)...{    
         long start=System.currentTimeMillis();    
         for(int i=0;i<N;i++)...{    
             int index=Collections.binarySearch(lst, values.get(i));    
             if(index!=i)    
                 System.out.println("***错误***");    
         }    
         return System.currentTimeMillis()-start;    
     }    
     public static void main(String args[])...{    
         System.out.println("ArrayList消耗时间:"+timeList(new ArrayList(values)));    
         System.out.println("LinkedList消耗时间:"+timeList(new LinkedList(values)));    
     }    
}

 

 

我得到的输出是:ArrayList消耗时间:15
                 LinkedList消耗时间:2596


这个结果不是固定的,但是基本上ArrayList的 时间要明显小于LinkedList的时间。因此在这种情况下不宜用LinkedList。二分查找法使用的随机访问(random access)策略,而LinkedList是不支持快速的随机访问的。对一个LinkedList做随机访问所消耗的时间与这个list的大小是成比例 的。而相应的,在ArrayList中进行随机访问所消耗的时间是固定的。
这是否表明ArrayList总是比LinkedList性能要好呢?这并不一定,在某些情况 下LinkedList的表现要优于ArrayList,有些算法在LinkedList中实现时效率更高。比方说,利用 Collections.reverse方法对列表进行反转时,其性能就要好些。
看这样一个例子,加入我们有一个列表,要对其进行大量的插入和删除操作,在这种情况下 LinkedList就是一个较好的选择。请看如下一个极端的例子,我们重复的在一个列表的开端插入一个元素:

package com.mangocity.test;    
   
import java.util.*;    
public class ListDemo {    
     static final int N=50000;    
     static long timeList(List list){    
     long start=System.currentTimeMillis();    
     Object o = new Object();    
     for(int i=0;i<N;i++)    
         list.add(0, o);    
     return System.currentTimeMillis()-start;    
     }    
     public static void main(String[] args) {    
         System.out.println("ArrayList耗时:"+timeList(new ArrayList()));    
         System.out.println("LinkedList耗时:"+timeList(new LinkedList()));    
     }    
}

 

 

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

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


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

private static class Entry {    
         Object element;    
         Entry next;    
         Entry previous;    
     }

 

 

每个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 @ 2012-05-25 14:43 魔豆 阅读(11) 评论(0)  编辑

2012年4月20日 #

朋友有这么一个需求:他从网上查询到自己的通话记录,然后他想把所有北京的号码调出来,可是查到的号码不带归属地,只能一个个的查询,很麻烦,于是我写了一段javascript代码,可以批量查询,代码如下:

 

<!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>

</head>

<body>
<script type="text/javascript" src="js/jquery-1.6.2.min.js"></script>
<script language="javascript">
var timeout = 5;//每条记录查询延时时间,单位:秒
var strContent = "";
var strArray = "";
function getInfo()
{
	strContent = document.getElementById("strContent").value;
	strArray = strContent.split(navigator.appName=="Netscape"?"\n":"\r\n");
	$("#contentDiv").html("");
	getCity(0);
}

function getCity(i)
{
	var num = strArray[i].replace(new RegExp(" ","g"),"").replace(new RegExp("\t","g"),"");
	$.ajax({
		   type: "POST",
		   dataType:"jsonp",
		   url: "http://api.showji.com/Locating/20120413.aspx",
		   data: "m=" + num + "&output=json",
		   jsonpCallback:"querycallback",
		   success: function(msg){
		   $("#contentDiv").html($("#contentDiv").html() + "号码:" + num + "   城市:" + msg.City + "<br />");
		     i++;
			 if(i < strArray.length) {
				 setTimeout("getCity(" + i + ")", timeout * 1000);
			 }
		   }
		});
}
</script>
<form id="form1" name="form1" method="post" action="">
  <p>请输入手机号码(多条记录用回车换行):<br />
    <textarea name="strContent" id="strContent" cols="80" rows="12"></textarea>
    <input type="button" name="Button" value="查询号码所在城市" onclick="getInfo()" />
</p>
  <p id="contentDiv">   </p>
</form>

</body>
</html>

  

代码打包下载:http://files.cnblogs.com/modou/20120420.rar

 

注意内容:

1、代码用到了jquery,需要把jquery的对应代码添加进来

2、我使用的这个网址:http://api.showji.com/Locating/20120413.aspx 抓取的手机归属地,如果该网址发生变化,可以再重新到http://www.showji.com/ 获取相关网址,这个网址可以在该网站查询的时候,开启Fiddler2工具监控到。

3、可能是http://www.showji.com/ 做了限制,在一定时间内查询的次数过多就查询不到对应的结果了,我把查询时间的间隔设为5秒钟,如果号码比较多,等待的时间会比较长一些

posted @ 2012-04-20 10:57 魔豆 阅读(66) 评论(0)  编辑

2012年1月12日 #

将HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\View Source Editor\Editor Name的内容修改为

C:\\WINDOWS\\system32\\notepad.exe


或者直接执行这个注册表文件:20120112.zip

posted @ 2012-01-12 09:36 魔豆 阅读(59) 评论(0)  编辑

2011年12月17日 #

下载地址:http://files.cnblogs.com/modou/RssReader101.apk

支持版本:Android 2.1+

文件大小:189KB

发布时间:2011-12-17

更新内容:

1.界面稍作美化

2.修复第一次使用时,可能会无法加载列表的BUG

3.主界面更流畅的左右滑动体验,更改滑动处理方式

4.正文使用内置解析方式,不再默认使用浏览器打开,在正文内容最下放,依然可以使用浏览器查看原文

历史版本:

RSS阅读器For AndroidV1.0发布了 http://www.cnblogs.com/modou/articles/2244822.html

软件截图:


 


posted @ 2011-12-17 18:59 魔豆 阅读(28) 评论(0)  编辑

2011年12月10日 #

作为程序员,要取得非凡成就需要记住的15件事。
1.走一条不一样的路
在有利于自己的市场中竞争,如果你满足于“泯然众人矣”,那恐怕就得跟那些低工资国家的程序员们同场竞技了。

2.了解自己的公司
以我在医院、咨询公司、物流企业以及大技术公司工作的经验来看,这一点所言不虚。
不同公司的运营模式差异极大。如果你理解企业的运营模式,那你就不一样了!在这家公司中(或者对客户而言),你是参与业务运营的资产,你的工作能直接产生效益!

3.与最优秀的人为伍
很早以前,我喜欢打篮球,被分配到一个水平比较高的队里。一开始适应的确很困难,但环境的压力越大(重大比赛),我的长进也就越明显。
每个领域其实都一样:你周围人的水平(以及对你的期望)越高,你就会变得越优秀。

4.制造差异
每年学习一门新编程语言。为什么不呢?不断尝试新事物,你关注的技术种类越多,脚下的路就越宽广,你的职业生涯就会日新月异。不知道几年后Java的趋势如何?那就学习Clojure。学Ruby还是Python?这两种语言都可以试试啊。然后你才能知道哪种语言更适合某个特定的项目。看,掌握的语言多了,才能在需要的时候信手拈来吧。


5.畏惧,是最大的敌人
还是直接从书中摘一句吧:“在畏惧中做出的职业规划,很可能会让自己后半辈子就一直被‘圈禁’在小隔断里,永远不会有创造明天辉煌的时刻。没错,那样是安全,但有意思吗?”

6.要成为多面手
如果你掌握了所在领域的知识,那你只能是一名专业人士。用PHP编程?花点时间设置一台Apache服务器,让PHP和MySQL都跑起来。一直在用jQuery?试试Prototype。你懂了吧。

7.一个字:做
别指望别人过来教你该怎么做,出去,自己学着去做!

8.找一位好老师
找一位好老师可以让你在学习技术的时候有的放矢。作者给我们讲述了别人是怎么指导他学习的(顺便说一句,作者在这本书里讲了很多个人经历的小故事,他居然从一位演奏家转行来做软件开发!):“好好研究一下目录服务,熟悉一种UNIX变体,然后再掌握一门脚本语言。”
请记住这句禅宗谚语:“循路觅宗师,形影不相离,师知吾亦知,吾乃成宗师。”

9.主动教会别人
教会别人是一种最好的学习方式。写一篇博客能帮你搞清楚一个问题。为此,你必须先掌握很多材料,同时还要有条有理地讲给别人听(写作技能)。如书中所言:“要想知道自己是不是真的明白,你就讲给别人听听。”

10.实践,实践,再实践(训练)
只有进行大量实践(花大量的时间)才能掌握某种技术。看的很多,写的很少,遇到问题,改一改,又去读代码……(这样下去是不行的)。
要特别警惕拖延症。其实,往往只要有了开头就好办了。
自我加压,效果会更好。我曾在一篇博客中提到帕金森定律:紧张的时限可以让你提高工作效率。为什么不把这个定律用到学习上呢,比如说在y时间内学会x?


11.从小处入手
每天都取得一项小成果,每天都要坚持做(写在博客上?)。这样一来,你只能让自己比昨天更进步,而不能说自己比上星期进步了一点。

12.享受过程
关注当下,而不是目标,享受那些在追逐未来目标的途中可能无暇顾及的小胜利。人总要生活在当下。我享受编程的过程,就像享受编程的结果一样。


13.不要丧失危机感
越是成功,就越容易犯重大错误。永远不要忘了危机感,特别是要认识到你今天所知道的,到了明天可能就会一文不值。过去的荣耀不能保你永远无虞。
据书中所说,你最好是要让自己能够“通用”,而不要对哪种技术或哪个公司产生依赖。你所掌握的某些技能,甚至你的工作,到了明天都可能会变得毫无价值。因此要不断提高/丰富/扩展自己的技能。

14.推销自己
为某个项目贡献自己的一份力量,写一篇博客,共享自己的源代码,成为对某个社区有用的人。
当然,做这些事可能需要激情,要看你的爱好,但这些事也会间接地推广你的工作成果,证明你的实力,提高你的知名度。

15.关注市场
书中还提到了“预警极客”,也就是那些始终引领技术发展的人。这些人说过的话往往带有预见性,他们提到事物也许过几天就会成为头条新闻。关注这些人,常看他们的Twitter和博客。"

posted @ 2011-12-10 22:40 魔豆 阅读(196) 评论(1) 编辑

2011年11月10日 #

摘要: 利用业余时间,写了一个Android版本的RSS阅读器,具备RSS订阅以及阅读功能下载地址:http://files.cnblogs.com/modou/RssReader.apk支持版本:Android 2.1+文件大小:82KB发布时间:2011-11-10功能说明:1.支持Wifi/CMNET/CMWAP联网方式2.如果手机安装有UCWEB浏览器,优先使用UCWEB访问文章内容,没有安装UCWEB,使用默认浏览器3.支持检查新版本功能,使用菜单“检查更新”功能,发现新版本,可以在线升级到新版本4.发现BUG或者有好的建议,都可以通过菜单“反馈”留言给我,也可以在这里给我回复,非常感谢:)阅读全文
posted @ 2011-11-10 18:22 魔豆 阅读(77) 评论(2)  编辑

2011年9月29日 #

摘要: Win2003开机的时候,总是会弹出一个错误信息,一个服务控制管理器的对话框,修改注册表可以禁止出现这个对话框dos下regedit进入修改注册表:定位到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows新建一个DWORD值,名称为NoPopUpsOnBoot,数值为1阅读全文
posted @ 2011-09-29 17:11 魔豆 阅读(266) 评论(0)  编辑

2011年9月23日 #

摘要: 特点:功能强大,界面美观,使用简单演示地址:http://leotheme.cn/wp-content/uploads/Example/js/tipswindow/index.htmlJS文件下载:http://leotheme.cn/wp-content/uploads/Example/js/tipswindow/jquery.XYTipsWindow.2.8.js完整包下载:http://leotheme.cn/wp-content/uploads/Example/js/tipswindow/XY_Tips.rar阅读全文
posted @ 2011-09-23 16:21 魔豆 阅读(307) 评论(0)  编辑

摘要: 特别提示:xml 是可以动态生成的,但是在生成的时候要着重考虑 bcastr4.swf 、bcastr.xml 以及 图片的路径关系,另外需要注意 flash新版本 是不能跨域的,flash里面的链接和图片都是不能跨域的,就是说你的xml里面的的图片和链接地址都要跟xml是属于一个域名的~~网友冰淇淋小子建议:参数里面的图片和链接地址最好使用绝对路径。我们在进行网页编程时,难免会遇到需要进行图片轮换的地方,在这里向大家推荐 Bcastr 4.0 ,一款优秀的通用图片轮换播放器。使用 Bcastr 4.0 可以轻松的制作如上面所示的图片轮换效果,它有如下的特点:可以读取xml设置播放列表,自定义阅读全文
posted @ 2011-09-23 15:40 魔豆 阅读(577) 评论(2)  编辑

2011年9月3日 #

摘要: xp系统搜索文件内容,有一项可以按照“文件中的一个字或词组”搜索,默认情况下居然搜不到内容,汗,原来需要修改注册表,这个功能才能使用:运行regedit,编辑注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ContentIndex右侧FilterFilesWithUnknownExtensions子键(REG_DEWORD类型)的键值改为1。 如果注册表内没有这个子键,则建立一个,然手修改键值即可阅读全文
posted @ 2011-09-03 17:42 魔豆 阅读(273) 评论(0)  编辑

2011年9月1日 #

摘要: 该例子匹配字符串是否全为字母 public static void main(String[] args) { String str = "abcdef"; Matcher m = Pattern.compile("[a-zA-Z]+").matcher(str); System.out.println(m.matches()); } 注意到这里使用的是m.matches(),而不是m.find(),两者的区别在于,matches是将整个输入和表达式进行匹配,find只是查找匹配的部分,只要找到匹配的内容就返回true阅读全文
posted @ 2011-09-01 17:27 魔豆 阅读(99) 评论(0)  编辑

2011年8月5日 #

摘要: oracle的监听突然打不开了,很是郁闷,到网上查了一下,基本上都是说是注册表少ImagePath,我找到对应位置,ImagePath没问题然后敲命令,看看到底是什么问题,进入dos,输入命令:lsnrctl start提示错误信息如下:Copyright (c) 1991, 2005, Oracle. All rights reserved.启动tnslsnr: 请稍候...TNSLSNR for 32-bit Windows: Version 10.2.0.1.0 - Production系统参数文件为c:\oracle\product\10.2.0\db_2\network\admin\阅读全文
posted @ 2011-08-05 16:44 魔豆 阅读(298) 评论(0)  编辑

2011年7月26日 #

摘要: Java的开源生态系统是强大而健康的,这是我们(Oreilly)创建OSCON Java(Open Source ConventionJava)的主要原因之一。在过去10年中,一些项目已经被广泛接受,并且已经统治了Java软件开发世界,一些甚至影响到了用户的日常生活。 1. JUnit Kent Beck先生关于Smalltalk的单元测试被Kent Beck 和Erich Gamma带进Java——JUnit。在这十年里,JUnit带来了测试驱动开发的普及浪潮。许多其它流行语言的单元测试版本也跟着被创造出来了,例如.NET、C、Python、Perl。 2. Eclipse 刚进入20世纪.阅读全文
posted @ 2011-07-26 18:12 魔豆 阅读(87) 评论(0)  编辑

2011年7月16日 #

摘要: 代码如下:<?xml version="1.0" encoding="utf-8"?><s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> &阅读全文
posted @ 2011-07-16 19:33 魔豆 阅读(447) 评论(0)  编辑

摘要: Flashpaper安装目录下有一个模板文件Interface\DefaultViewer2.swf,替换该文件即可!替换后整个toolbar都会去掉,当然也包括打印功能DefaultViewer2.swf下载阅读全文
posted @ 2011-07-16 08:47 魔豆 阅读(304) 评论(0)  编辑