《Java特种兵》1.6 常见的目录与工具包

简介:

本文是《Java特种兵》的样章,感谢博文视点和作者授权本站发布

1.6 常见的目录与工具包

很多做Java开发的同学们,在达到一定程度后,开始“身手不凡”,成为大侠,在了解了底层后,开始自己写东西。这个阶段容易纠结的就是重复制造,在了解了底层后我们需要提升知识面,知道哪些是别人提供的,哪些是需要我们自己写的。

Java的三方包无穷无尽,无法一一列举这些工具包,但是我们应当知道有许多别人写好的工具包可以直接拿来使用,以及如何来寻找这些工具包,基础知识可以帮助我们快速学习新的工具包,以及掌握它的本质。同时,这里的内容也算是为“源码篇”做一个简单铺垫。

首先,要知道Java本身提供的一些源码放在哪里。一般来讲,安装完JDK后,在JDK的根目录下会有一个叫“src.zip”的压缩包,解压后是一个目录,其中包含了常见的Java源码,但是以sun开头的文章是找不到的,你可以通过一些反编译手段得到,也可以在OpenJDK上找到一些源码,主要目的是看懂意思和知道它的坑。

有工具后,从哪里开始看起?从我们用到的API看起,当你需要用到某个API的时候,就可以查看是否有相关的API,简单记录下来。看看是否有更好的方式,要有个大致的笔记。例如,对于List的简单使用,小胖哥问几个小问题。

◎ 将ArrayList转换为LinkedList用什么方法?各自的好坏?

◎ 将集合类、数组做一次浅拷贝用什么方法?用for循环还是别的方法?

◎ 对List、数组做排序用什么方法?

其实在对集合类、数组操作上,有一些Java本身提供的工具类(静态工具方法),分别位于java.util.Collections、java.util.Arrays类中,它们拥有非常多的对集合类和数组的操作动作,足以满足绝大部分需求。下面通过两个场景给大家一点感性认识。

场景1:通过常量构造一个ArrayList返回。

最直接的写法是:


List<String>list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");


用工具就可以这样写:


List<String> list = Arrays.asList("a" , "b" , "c");


或许你认为就是语法糖而已,而Java本身要的就是简单,我们希望将更多的精力花在实际创造上,这样的代码可能会在系统中反反复复出现,其实很多时候是枯燥无味的。

场景2:中文拼音排序。

代码片段1-6 一个简单的中文拼音排序


public class SampleChineseSort {

	@SuppressWarnings("rawtypes")
	private final static Comparator CHINA_COMPARE
			= Collator.getInstance(java.util.Locale.CHINA);

	public static void main(String []args) {
		sortArray();
		sortList();
	}

	private static void sortList() {
		List<String>list = Arrays.asList("张三", "李四", "王五");
		Collections.sort(list , CHINA_COMPARE);
		for(String str : list) {
			System.out.println(str);
		}
	}

	private static void sortArray() {
		String[] arr = {"张三", "李四", "王五"};
		Arrays.sort(arr, CHINA_COMPARE);
		for(String str : arr) {
			System.out.println(str);
		}
	}
}


关于排序不仅仅如此,有些时候我们还需要用对象排序,对象怎么排序呢?当然是基于对象内部某些自定义的属性来排序了。而不论用什么来做Java排序,都需要使用数字来排序,也就是要有大小关系。Java提供了Comparable和Comparator两种接口(两种接口是分开用的),Comparable接口需要让列表中的对象来实现接口中的方法compareTo(E),返回正数表示当前对象比传入对象大,当前对象会排序靠后;返回0表示等值,返回负数表示当前对象比传入对象小,排序靠前。也就是你告诉Java对象之间的大小关系(而谁大谁小是你自己决定的),Java就会从小到大排列;如果想要反向排序,那么就将返回值“取反”;如果想要按照多个字段排序,在这个方法内部也是可以完成的。

大家可能发现这样的方式不是太灵活,因为一个对象实现接口后,这个方法就固定了。也就是说,它的排序算法已经固定了,如果它的排序算法不是固定的,是可以动态调整的,那么就用Comparator接口来扩展,它独立于被排序的对象单独存在,当需要排序的时候,以参数的形式传递,上面例子中的“CHINA_COMPARE”就是一个Comparator实例。你也可以自己实现一个自定义对象的排序方式来满足特定对象的要求,如果同样的对象一会想这样排序,一会想那样排序,就只需要使用不同的Comparator实例即可。

 

这是一种基本的封装思路,Java就是希望让开发者关注更少的事情,它帮你去完成排序。这种思路也衍生到SortedSet中的排序,也在Timer、ScheduleThreadPool调度任务中使用(确切说是内部包装的,在PriorityQueue中使用,5.6节会详细阐述)。关于这些内容,可以参考胖哥的个人博客:http://blog.csdn.net/xieyuooo/article/details/8611198。

例子举不完,Java本身提供的工具非常多,而且每个版本都会有新的工具包出现。除此之外,还有许多的二方包、三方包都提供了大量的工具类,这里就不再逐个举例了。Java是希望将一些复杂的逻辑细节封装在工具中,让业务代码尽量干净、整洁,容易维护。反之,如果业务代码中出现了大量的排序、字符串处理、日期处理、类型转换、数组或集合类循环拷贝与组装、文件处理、网络IO等片段,我们就会感觉代码“不干净”,这样的代码会在许多地方出现,这也意味着如果需要修改则要到许多地方去完成,而很多时候我们不知道到哪里去修改。这些代码会让我们的思路不断在技术和业务之间切换,没法专心做好业务细节,更没法深度挖掘业务。技术本身是在业务驱动下才能发挥作用的,而人在业务驱动下去学习技术是能得到最佳实践的。

例如,Apache就提供了许多有用的三方包给我们使用,很多人都应该熟知StringUtils这个工具包吧,类似的还有很多,如upload、连接池、log4j、字符集处理等都可以算是工具包,这些工具包提供了大量API,大多数情况下无须自己去实现处理细节,因为它们的正确性和性能是经过很多公司验证的,如果有问题大家都会知道。所以,我们在注重功底的基础上也需要大量的学习,铺开知识面,才能有选择,但“深知内在细节是我们量化选择的条件”。

当然,不是所有的工具包都能完全满足我们的需求,而往往“最烦人”的就是这个工具包满足一部分需求,那个工具包满足一部分需求,而将这些工具包组合起来使用可能比自己写一个还麻烦,翻译为基础代码还会有一大堆的冗余,此时就可以考虑扩展了。

每个场景都会有一些变化,开源的工具仅仅是提供一些通用的处理,同时提供一种Java封装思想,许多代码也值得我们去参考。因此当遇到个性化问题的时候,并非别人没提供自己就不写了,个性化包装就是一个优秀程序员需要去承担的责任,所以老A程序员除了拥有非凡的功力外,也同时需要深知所涉及领域的业务和个性化,这样才能针对业务做出一个“很爽”的架构体系。

胖哥说话好像在“绕圈”,怎么又绕回功底来了?其实胖哥此处再谈功底,是要说明在这个基础上根据实际的场景应当“因地制宜”才能“事半功倍”,同时要以大量的知识面为基础,充分利用现有的资源。 

目录
相关文章
|
3月前
|
安全 Java API
JAVA并发编程JUC包之CAS原理
在JDK 1.5之后,Java API引入了`java.util.concurrent`包(简称JUC包),提供了多种并发工具类,如原子类`AtomicXX`、线程池`Executors`、信号量`Semaphore`、阻塞队列等。这些工具类简化了并发编程的复杂度。原子类`Atomic`尤其重要,它提供了线程安全的变量更新方法,支持整型、长整型、布尔型、数组及对象属性的原子修改。结合`volatile`关键字,可以实现多线程环境下共享变量的安全修改。
|
4月前
|
安全 Java 调度
解锁Java并发编程高阶技能:深入剖析无锁CAS机制、揭秘魔法类Unsafe、精通原子包Atomic,打造高效并发应用
【8月更文挑战第4天】在Java并发编程中,无锁编程以高性能和低延迟应对高并发挑战。核心在于无锁CAS(Compare-And-Swap)机制,它基于硬件支持,确保原子性更新;Unsafe类提供底层内存操作,实现CAS;原子包java.util.concurrent.atomic封装了CAS操作,简化并发编程。通过`AtomicInteger`示例,展现了线程安全的自增操作,突显了这些技术在构建高效并发程序中的关键作用。
70 1
|
2月前
|
Java Apache Maven
Java/Spring项目的包开头为什么是com?
本文介绍了 Maven 项目的初始结构,并详细解释了 Java 包命名惯例中的域名反转规则。通过域名反转(如 `com.example`),可以确保包名的唯一性,避免命名冲突,提高代码的可读性和逻辑分层。文章还讨论了域名反转的好处,包括避免命名冲突、全球唯一性、提高代码可读性和逻辑分层。最后,作者提出了一个关于包名的问题,引发读者思考。
Java/Spring项目的包开头为什么是com?
|
3月前
|
Java API 数据处理
Java 包(package)的作用详解
在 Java 中,包(package)用于组织和管理类与接口,具有多项关键作用:1)系统化组织代码,便于理解和维护;2)提供命名空间,避免类名冲突;3)支持访问控制,如 public、protected、默认和 private,增强封装性;4)提升代码可维护性,实现模块化开发;5)简化导入机制,使代码更简洁;6)促进模块化编程,提高代码重用率;7)管理第三方库,避免命名冲突;8)支持 API 设计,便于功能调用;9)配合自动化构建工具,优化项目管理;10)促进团队协作,明确模块归属。合理运用包能显著提升代码质量和开发效率。
|
3月前
|
Java 数据安全/隐私保护
Java 包(package)的使用详解
Java中的包(`package`)用于组织类和接口,避免类名冲突并控制访问权限,提升代码的可维护性和可重用性。通过`package`关键字定义包,创建相应目录结构即可实现。包可通过`import`语句导入,支持导入具体类或整个包。Java提供多种访问权限修饰符(`public`、`protected`、`default`、`private`),以及丰富的标准库包(如`java.lang`、`java.util`等)。合理的包命名和使用对大型项目的开发至关重要。
|
3月前
|
存储 缓存 监控
Java——图片文件位于 bin 目录下,下载新图片会导致应用程序重启
【9月更文挑战第22天】在Java应用中,若图片位于bin目录下且下载新图片导致应用重启,可能是因为部署方式不当或资源监控机制过于敏感。解决方法包括:更改图片存储位置至独立目录;配置应用服务器减少资源监控敏感度;使用独立资源服务器托管静态资源;优化代码减少资源重复加载。具体方案需根据应用实际情况和技术栈调整。
|
4月前
|
Java Maven 数据库
|
4月前
|
JavaScript Java API
Java日志通关(二) - Slf4j+Logback 整合及排包
作者日常在与其他同学合作时,经常发现不合理的日志配置以及五花八门的日志记录方式,后续作者打算在团队内做一次Java日志的分享,本文是整理出的系列文章第二篇。
|
4月前
|
Java
Java应用结构规范问题之在biz层的convert包实现转换的问题如何解决
Java应用结构规范问题之在biz层的convert包实现转换的问题如何解决
|
4月前
|
Java
Java 基础语法-面试题(54-63道)(数组+类+包)
Java 基础语法-面试题(54-63道)(数组+类+包)
46 16
下一篇
无影云桌面