Java文件　字符　统计工具　import　java　.　util　.　TreeMap　;　public　class　CharacterStatistics　{　public　static　TreeMap　<　Character　,　Integer　>　statistics　(　byte　[　]　data　)　{　String　dataString　=　new　String　(　data　)　;　TreeMap　<　Character　,　Integer　>　treeMap　=　new　TreeMap　<　Character　,　Integer　>　(　)　;　int　length　=　dataString　.　length　(　)　;　for　(　int　i　=　0　;　i　<　length　;　i　++　)　{　char　character　=　dataString　.　charAt　(　i　)　;　Integer　time　=　treeMap　.　get　(　character　)　;　if　(　time　==　null　)　{　time　=　0　;　}　time　++　;　treeMap　.　put　(　character　,　time　)　;　}　return　treeMap　;　}　}　import　java　.　io　.　File　;　import　java　.　io　.　FileInputStream　;　import　java　.　io　.　IOException　;　public　class　FileLoader　{　public　static　byte　[　]　getData　(　String　srcFileName　)　throws　IOException　{　File　srcFile　=　new　File　(　srcFileName　)　;　FileInputStream　fis　=　new　FileInputStream　(　srcFile　)　;　byte　[　]　data　=　new　byte　[　(　int　)　srcFile　.　length　fis　.　read　(　data　)　;　fis　.　close　(　)　;　return　data　;　}　}　import　java　.　io　.　PrintStream　;　import　java　.　util　.　Set　;　import　java　.　util　.　TreeMap　;　public　class　FileSaver　{　public　static　void　save　(　TreeMap　<　Character　,　Integer　>　treeMap　,　String　destFileName　)　throws　Exception　{　PrintStream　printStream　=　new　PrintStream　(　destFileName　)　;　Set　<　Character　>　keySet　=　treeMap　.　keySet　(　)　;　for　(　char　ch　:　keySet　)　{　printStream　.　println　(　ch　+　"\t"　+　treeMap　.　get　(　ch　printStream　.　close　import　java　.　util　.　TreeMap　;　import　javax　.　swing　.　JOptionPane　;　/**　*　输入样例:　*　C:\info.txt　*　*　注意:　*　1.如果要统计频率,,注意除以总字符数　*　2.如果要分析的不是字符而是词组。。。emmm,野鸡了　*　3.如果文件很大,,几GB,String不够了,咋整?(温馨提示:RandomAccessFile)　*　@author　BlankSpace　*/　public　class　Main　{　public　static　void　main　(　String　[　]　args　)　{　String　srcFileName　=　JOptionPane　.　showInputDialog　(　"请您输入源文件路径"　)　;　String　destFileName　=　srcFileName　+　"_stat.txt"　;　try　{　byte　[　]　data　=　FileLoader　.　getData　(　srcFileName　)　;　TreeMap　<　Character　,　Integer　>　treeMap　=　CharacterStatistics　.　statistics　(　data　)　;　FileSaver　.　save　(　treeMap　,　destFileName　)　;　}　catch　(　Exception　ex　)　{　JOptionPane　.　showMessageDialog　(　null　,　"操作异常"　)　;　System　.　exit　(　1　)　;　}　JOptionPane　.　showMessageDialog　(　null　,　"输入完毕"Java文件大小　转换　工具类　(B,KB,MB,GB,TB,PB之间的大小转换)　有时候要做出如下所示的展示文件大小的效果时候,需要对文件大小进行转换,然后再进行相关的代码逻辑编写。下面是一个　Java文件大小　转换　工具类　,可以进行...　有时候要做出如下所示的展示文件大小的效果时候,需要对文件大小进行转换,然后再进行相关的代码逻辑编写。　下面是一个Java文件大小转换工具类　,可以进行B,KB,MB,GB,TB,PB之间的大小转换。该工具类来源于博客:(http://blog.csdn.net/xmtblog/article/details/27194021)存储大小(单位)转换器.　*/　public　enum　SizeConverter　{　/**　*　转换任意单位的大小,　返回结果会包含两位小数但不包含单位.　*/　Arbitrary　{　@Override　public　String　convert　(　没有对比就不会知道两者之间的差异,程序员或者其他办公人员经常会使用一些对比　工具　对某些　文件　进行对比、比较,从而找到两者之间的差异。目前相关的软件有很多,乱花渐入迷人眼,导致我们犯了选择困难症。　Beyond...　没有对比就不会知道两者之间的差异,程序员或者其他办公人员经常会使用一些对比工具对某些文件进行对比、比较,从而找到两者之间的差异。目前相关的软件有很多,乱花渐入迷人眼,导致我们犯了选择困难症。　Beyond　Compare:文件对比工具(强推)　Beyond　Compare　是一款不可多得的专业级的文件夹和文件对比工具。使用它可以查看所有文件、匹配的文件、不匹配的文件等,使用不同的颜色区分以便轻松辨识,查看方便。现在点击“http://www.beyondcompare.cc/xiazai.html”即可免费使用该软件!　Diffpdf　:pdf文件比较工具　diffpdf是一个非常简单的pdf文件比较工具,它能轻松的对两个pdf文件进行字数,页数等内容的比较。不同之处以高亮形式显示,从而轻松的完成了繁杂的比较任务,省时省力。　WinNc:文件管理工具　WinNc　是一款非常好用的文件管理工具,该软件除了提供一般的重命名、查看、编辑、复制、删除、移动、新建等功能外,还提供了统计目录大小和压缩解压缩的功能!并同时具备了文本比较、加密、编译、转化、刻录、分割、合并、同步和创建ISO文件的功能!　Excel　:　对比查询专家　Excel对比查询专家是一款能够有效地帮助用户快速文档比较和数据汇总的excel文件对比工具。软件为用户提供了它提供了工作表对比、全文档比较、分组汇总、分页汇总、文档连接等九个功能模块,能够帮你自动对比汇总,提高您的工作效率,经常要做数据对比汇总的朋友推荐使用。　UltraCompare　Pro:文件内容对比工具　UltraCompare　Professional是一款拥有所有功能的文件内容对比工具。无论你是简单的编辑文本,建筑应用,维护数据库,或建设网站,UltraCompare都可以满足你的要求。　简单来说,你可以用它来比较两个文本文件的不同,也可以比较两个exe　文件的不同,还可以用它来比较两个文件夹及其子文件夹内文件的不同。　用户需要根据自己的需求进行选择,Beyond　Compare除了对比文件、文件夹之外,还可以对压缩文件进行对比,它是对比工具中的佼佼者。选择使用合适而功能强大的对比工具,不仅可以提高工作效率,还能保证工作的准确性。　CountDownLatch、CyclicBarrier　和Semaphore　工具类　提供了一种并发流程控制的手段,Exchanger　工具类　则提供了在线程间交换数据的一种手段。本章会配合一些应用场景来介绍如何使用这些　工具类　。　一、等待多线程完成的...　前言:　在JDK　的并发包里提供了几个非常有用的并发工具类。CountDownLatch、CyclicBarrier　和Semaphore　工具类提供了一种并发流程控制的手段,Exchanger　工具类则提供了在线程间交换数据的一种手段。本章会配合一些应用场景来介绍如何使用这些工具类。　一、等待多线程完成的　CountDownLatch　CountDownLatch　允许一个或多个线程等待其他线程完成操作。　假如有这样一个需求:我们需要解析一个　Excel　里多个　sheet　的数据,此时可以考虑使用多线程,每个线程解析一个　sheet　里的数据,等到所有的　sheet　都解析完之后,程序需要提示解析完成。在这个需求中,要实现主线程等待所有线程完成　sheet　的解析操作,最简单的做法是使用　join()　方法,如代码清单所示。　public　class　JoinCountDownLatchTest　{　public　static　void　main　(　String　[　]　args　)　throws　InterruptedException　{　Thread　parser1　=　new　Thread　System　.　out　.　println　(　"parser1　finish"Thread　parser2　=　new　Thread　System　.　out　.　println　(　"parser2　finish"parser1　.　start　(　)　;　parser2　.　start　(　)　;　parser1　.　join　(　)　;　parser2　.　join　(　)　;　System　.　out　.　println　(　"all　parser　finish"join　用于让当前执行线程等待　join　线程执行结束。其实现原理是不停检查　join　线程是否存活,如果　join　线程存活则让当前线程永远等待。其中,wait(0)　表示永远等待下去,代码片段如下。　while　(　isAlive　(　)　)　{　wait　(　0　)　;　}　直到　join　线程中止后,线程的　this.notifyAll()　方法会被调用,调用　notifyAll()　方法是在　JVM　里实现的,所以在　JDK　里看不到,大家可以查看　JVM　源码。　在JDK　1.5　之后的并发包中提供的　CountDownLatch　也可以实现　join　的功能,并且比　join　的功能更多,如代码清单所示。　public　class　CountDownLatchTest　{　static　CountDownLatch　c　=　new　CountDownLatch　(　2　)　;　public　static　void　main　(　String　[　]　args　)　throws　InterruptedException　{　new　Thread　System　.　out　.　println　(　1　)　;　c　.　countDown　(　)　;　System　.　out　.　println　(　2　)　;　c　.　countDown　start　(　)　;　c　.　await　(　)　;　System　.　out　.　println　(　"3"CountDownLatch　的构造函数接收一个　int　类型的参数作为计数器,如果你想等待　N　个点完成,这里就传入　N。　当我们调用　CountDownLatch　的countDown　方法时,N　就会减　1,CountDownLatch　的await　方法会阻塞当前线程,直到　N　变成零。由于　countDown　方法可以用在任何地方,所以这里说的　N　个点,可以是　N　个线程,也可以是　1　个线程里的　N　个执行步骤。用在多个线程时,只需要把这个　CountDownLatch　的引用传递到线程里即可。　如果有某个解析　sheet　的线程处理得比较慢,我们不可能让主线程一直等待,所以可以使用另外一个带指定时间的　await　方法　——　await(long　time,TimeUnit　unit),这个方法等待特定时间后,就会不再阻塞当前线程。join也有类似的方法。　注意:计数器必须大于等于　0,只是等于　0　时候,计数器就是零,调用　await　方法时不会阻塞当前线程。CountDownLatch　不可能重新初始化或者修改　CountDownLatch　对象的内部计数器的值。一个线程调用　countDown　方法　happen-before,另外一个线程调用　await　方法。　二、同步屏障　CyclicBarrier　CyclicBarrier　的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。　2.1　CyclicBarrier　简介　CyclicBarrier　默认的构造方法是　CyclicBarrier(int　parties),其参数表示屏障拦截的线程数量,每个线程调用　await　方法告诉　CyclicBarrier　我已经到达了屏障,然后当前线程被阻塞。　示例代码如代码清单所示。　public　class　CyclicBarrierTest　{　static　CyclicBarrier　c　=　new　CyclicBarrier　(　2　)　;　public　static　void　main　(　String　[　]　args　)　{　new　Thread　try　{　c　.　await　(　)　;　}　catch　(　Exception　ignored　)　{　}　System　.　out　.　println　(　1　start　(　)　;　try　{　c　.　await　(　)　;　}　catch　(　Exception　ignored　)　{　}　System　.　out　.　println　(　2　)　;　}　}　因为主线程和子线程的调度是由　CPU　决定的,两个线程都有可能先执行,所以会产生两种输出,第一种可能输出如下。　第二种可能输出如下。　如果把　new　CyclicBarrier(2)　修改成　new　CyclicBarrier(3),则主线程和子线程会永远等待,因为没有第三个线程执行　await　方法,即没有第三个线程到达屏障,所以之前到达屏障的两个线程都不会继续执行。　CyclicBarrier　还提供一个更高级的构造函数　CyclicBarrier(int　parties,Runnable　barrierAction),用于在线程到达屏障时,优先执行barrierAction,方便处理更复杂的业务场景,如代码清单所示。　public　class　CyclicBarrierTest2　{　static　CyclicBarrier　c　=　new　CyclicBarrier　(　2　,　new　A　(　)　)　;　public　static　void　main　(　String　[　]　args　)　{　new　Thread　try　{　c　.　await　(　)　;　}　catch　(　Exception　ignored　)　{　}　System　.　out　.　println　(　1　start　(　)　;　try　{　c　.　await　(　)　;　}　catch　(　Exception　ignored　)　{　}　System　.　out　.　println　(　2　)　;　}　static　class　A　implements　Runnable　{　@Override　public　void　run　(　)　{　System　.　out　.　println　(　3　因为　CyclicBarrier　设置了拦截线程的数量是　2,所以必须等代码中的第一个线程和线程　A　都执行完之后,才会继续执行主线程,然后输出　2,所以代码执行后的输出如下。　2.2　CyclicBarrier　的应用场景　CyclicBarrier　可以用于多线程计算数据,最后合并计算结果的场景。例如,用一个　Excel　保存了用户所有银行流水,每个　Sheet　保存一个账户近一年的每笔银行流水,现在需要统计用户的日均银行流水,先用多线程处理每个　sheet　里的银行流水,都执行完之后,得到每个　sheet　的日均银行流水,最后,再用　barrierAction　用这些线程的计算结果,计算出整个　Excel　的日均银行流水,如代码清单所示。　/**　*　银行流水处理服务类　*/　public　class　BankWaterService　implements　Runnable　{　//　创建4个屏障,处理完之后执行当前类的run方法　private　final　CyclicBarrier　c　=　new　CyclicBarrier　(　4　,　this　)　;　//　假设只有4个sheet,所以只启动4个线程　private　final　Executor　executor　=　Executors　.　newFixedThreadPool　(　4　)　;　//　保存每个sheet计算出的银流结果　private　final　ConcurrentHashMap　<　String　,　Integer　>　sheetBankWaterCount　=　new　ConcurrentHashMap　private　void　count　(　)　{　for　(　int　i　=　0　;　i　<　4　;　i　++　)　{　executor　.　execute　计算当前sheet的银流数据,计算代码省略　sheetBankWaterCount　.　put　(　Thread　.　currentThread　(　)　.　getName　(　)　,　1　)　;　//　银流计算完成,插入一个屏障　try　{　c　.　await　(　)　;　}　catch　(　Exception　ignored　Override　public　void　run　(　)　{　int　result　=　0　;　//　汇总每个sheet计算出的结果　for　(　Entry　<　String　,　Integer　>　sheet　:　sheetBankWaterCount　.　entrySet　result　+=　sheet　.　getValue　将结果输出　sheetBankWaterCount　.　put　(　"result"　,　result　)　;　System　.　out　.　println　(　result　)　;　}　public　static　void　main　(　String　[　]　args　)　{　BankWaterService　bankWaterCount　=　new　BankWaterService　(　)　;　bankWaterCount　.　count　使用线程池创建　4　个线程,分别计算每个　sheet　里的数据,每个　sheet　计算结果是　1,再由　BankWaterService　线程汇总　4　个sheet　计算出的结果,输出结果如下。　2.3　CyclicBarrier　和CountDownLatch　的区别　CountDownLatch　的计数器只能使用一次,而CyclicBarrier　的计数器可以使用　reset()　方法重置。所以　CyclicBarrier　能处理更为复杂的业务场景。例如,如果计算发生错误,可以重置计数器,并让线程重新执行一次。　CyclicBarrier　还提供其他有用的方法,比如　getNumberWaiting　方法可以获得　CyclicBarrier阻塞的线程数量。isBroken()　方法用来了解阻塞的线程是否被中断。　代码清单执行完之后会返回　true,其中　isBroken　的使用代码如代码清单所示。　public　class　CyclicBarrierTest3　{　static　CyclicBarrier　c　=　new　CyclicBarrier　(　2　)　;　public　static　void　main　(　String　[　]　args　)　{　Thread　thread　=　new　Thread　try　{　c　.　await　(　)　;　}　catch　(　Exception　ignored　thread　.　start　(　)　;　thread　.　interrupt　(　)　;　try　{　c　.　await　(　)　;　}　catch　(　Exception　e　)　{　System　.　out　.　println　(　c　.　isBroken　输出如下所示。　true　三、控制并发线程数的　Semaphore　Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。　多年以来,我都觉得从字面上很难理解　Semaphore　所表达的含义,只能把它比作是控制流量的红绿灯。比如××马路要限制流量,只允许同时有一百辆车在这条路上行使,其他的都必须在路口等待,所以前一百辆车会看到绿灯,可以开进这条马路,后面的车会看到红灯,不能驶　入××马路,但是如果前一百辆中有　5　辆车已经离开了××马路,那么后面就允许有　5　辆车驶入马路,这个例子里说的车就是线程,驶入马路就表示线程在执行,离开马路就表示线程执行完成,看见红灯就表示线程被阻塞,不能执行。　3.1　应用场景　Semaphore　可以用于做流量控制,特别是公用资源有限的应用场景,比如数据库连接。　假如有一个需求,要读取几万个文件的数据,因为都是　IO　密集型任务,我们可以启动几十个线程并发地读取,但是如果读到内存后,还需要存储到数据库中,而数据库的连接数只有　10　个,这时我们必须控制只有　10　个线程同时获取数据库连接保存数据,否则会报错无法获取数据库连接。　这个时候,就可以使用　Semaphore　来做流量控制,如代码清单所示。　public　class　SemaphoreTest　{　private　static　final　int　THREAD_COUNT　=　30　;　private　static　final　ExecutorService　threadPool　=　Executors　.　newFixedThreadPool　(　THREAD_COUNT　)　;　private　static　final　Semaphore　s　=　new　Semaphore　(　10　)　;　public　static　void　main　(　String　[　]　args　)　{　for　(　int　i　=　0　;　i　<　THREAD_COUNT　;　i　++　)　{　threadPool　.　execute　try　{　s　.　acquire　(　)　;　System　.　out　.　println　(　"save　data"　)　;　s　.　release　(　)　;　}　catch　(　Exception　ignored　threadPool　.　shutdown　在代码中,虽然有　30　个线程在执行,但是只允许　10　个并发执行。　Semaphore　的构造方法　Semaphore(int　permits)接受一个整型的数字,表示可用的许可证数量。Semaphore(10)表示允许　10　个线程获取许可证,也就是最大并发数是　10。　Semaphore　的用法也很简单,首先线程使用　Semaphore　的acquire()　方法获取一个许可证,使用完之后调用　release()　方法归还许可证。还可以用　tryAcquire()　方法尝试获取许可证。　3.2　其他方法　Semaphore　还提供一些其他方法,具体如下。　intavailablePermits():返回此信号量中当前可用的许可证数。　intgetQueueLength():返回正在等待获取许可证的线程数。　booleanhasQueuedThreads():是否有线程正在等待获取许可证。　void　reducePermits(int　reduction):减少　reduction　个许可证,是个　protected　方法。　Collection　getQueuedThreads():返回所有等待获取许可证的线程集合,是个　protected　方法。　四、线程间交换数据的　Exchanger　Exchanger(交换者)是一个用于线程间协作的工具类。Exchanger　用于进行线程间的数据交换。它提供一个同步点,在这个同步点,两个线程可以交换彼此的数据。这两个线程通过　exchange　方法交换数据,如果第一个线程先执行　exchange()　方法,它会一直等待第二个线程也　执行　exchange　方法,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方。　下面来看一下　Exchanger　的应用场景。　Exchanger　可以用于遗传算法,遗传算法里需要选出两个人作为交配对象,这时候会交换两人的数据,并使用交叉规则得出　2　个交配结果。Exchanger　也可以用于校对工作,比如我们需要将纸制银行流水通过人工的方式录入成电子银行流水,为了避免错误,采用　AB　岗两人进行录入,录入到　Excel　之后,系统需要加载这两个　Excel,并对两个　Excel　数据进行校对,看看是否录入一致,代码如代码清单所示。　public　class　ExchangerTest　{　private　static　final　Exchanger　<　String　>　exgr　=　new　Exchanger　<　String　>　(　)　;　private　static　final　ExecutorService　threadPool　=　Executors　.　newFixedThreadPool　(　2　)　;　public　static　void　main　(　String　[　]　args　)　{　threadPool　.　execute　try　{　String　A　=　"银行流水A"　;　//　A录入银行流水数据　exgr　.　exchange　(　A　)　;　}　catch　(　Exception　ignored　threadPool　.　execute　try　{　String　B　=　"银行流水B"　;　//　B录入银行流水数据　String　A　=　exgr　.　exchange　(　"B"　)　;　System　.　out　.　println　(　"A和B数据是否一致:"　+　A　.　equals　(　B　)　+　",A录入的是:"　+　A　+　",B录入是:"　+　B　)　;　}　catch　(　Exception　ignored　threadPool　.　shutdown　执行结果如下:　A和B数据是否一致:　false　,A录入的是:银行流水A,B录入是:银行流水B　如果两个线程有一个没有执行　exchange()　方法,则会一直等待,如果担心有特殊情况发生,避免一直等待,可以使用　exchange(V　x,longtimeout,TimeUnit　unit)设置最大等待时长。　一、直接上代码:　package　com.cycares.crm.utils.ExcelUtil;　import　java　.io.File;　import　java　.io.FileInputStream;...import　java　.io.FileOutputStream;...import　java　.io.IOException;...import　java　.util.ArrayL　JAVA　常用　工具类　(根据GITHUB代码　统计　)　从Google你能搜索到大量的关于Struts,Spring,Hibernate,iBatis等比较　大　的框架的资料,但是很少有人去关注一些小的工具包,但是当你真正知道了这些包的用处之后,你会发现它能很...　jhat　是Java　堆分析　工具　(　Java　heap　Analyzes　Tool).　在JDK6u7之后成为标配.　使用该命令需要有一定的　Java　开发经验.　jhat　命令解析　Java　堆转储　文件　,并启动一个　web　server.　然后用浏览器来查看/浏览　dump　出来的　heap.　...　文章目录1　java　分页　工具类　(极简版)2　java　分页查询　工具类　(极简版)2.1　分页查询　工具类　2.2　java　防止　SQL　注入　工具类　3　mybatis　mapper　文件　中分页查询应用4　service　层分页查询的应用　1　java　分页　工具类　(极简版)　...　转自　Java　面试题全集(上)...import　java　.io.BufferedReader;　import　java　.io.FileReader;　import　java　.io.IOException;　public　final　class　CountStringUti　java　大文件　拆分为小　文件　总结的Android开发中常用的　工具类　,　大　部分同样适用于　Java　。　目前包括HttpUtils、DownloadManagerPro、ShellUtils、PackageUtils、PreferencesUtils、JSONUtils、FileUtils、ResourceUtils、StringUtils、...　jstack --　如果　java　程序崩溃生成core　文件　,jstack　工具　可以用来获得core　文件　的java　stack和native　stack的信息,从而可以轻松地知道　java　程序是如何崩溃和在程序何处发生问题。另外,jstack　工具　还可以附属　import　java　.io.File;　import　java　.io.FileInputStream;　import　java　.text.DecimalFormat;　/**　*　Created　by　Administrator　on　2018/6/22　0022.　*/　public　class　FileSizeUtil　{　private　static　final　Strin...　代码实现了　文件　操作　类　接口:　Apache　POI　是用　Java　编写的免费开源的跨平台的　Java　API,Apache　POI提供API给Java　程式对Microsoft　Office格式档案读和写的功能。　场景:　1月底,财务需要将所有人的薪资　统计　之后发给领导,可登录系统将所有员工的...　java　探针利用了　java　Agent　+　ASM字节码注入　工具　实现了动态修改　类文件　的功能。像skywalking和arthas都使用到了这个技术。　具体原理为:　jdk1.5以后引入了　java　Agent技术,　java　Agent是运行方法之前的拦截器。我们利用...　Java　极速读取超大　文件Java　读取超大　文件　的几种方法传统Block　IO读入使用NIO零拷贝读实际执行效果使用BufferReader　执行效果使用改造后的NIO零拷贝的效果总结注意事项FAQ最重要的事　Java　读取超大　文件　的几种方法　在这里...　java　读取　文件　最后N行　源代码下载地址:http://www.zuidaima.com/share/1550463669226496.