🦥 PrintStream和PrintWriter
type
status
date
slug
summary
tags
category
icon
password
Property
 
PrintStream是一种FilterOutputStream,它在OutputStream的接口上,额外提供了一些写入各种数据类型的方法:
  • 写入intprint(int)
  • 写入booleanprint(boolean)
  • 写入Stringprint(String)
  • 写入Objectprint(Object),实际上相当于print(object.toString())
  • ...
以及对应的一组println()方法,它会自动加上换行符。
我们经常使用的System.out.println()实际上就是使用PrintStream打印各种数据。其中,System.out是系统默认提供的PrintStream,表示标准输出:
System.err是系统默认提供的标准错误输出。
PrintStreamOutputStream相比,除了添加了一组print()/println()方法,可以打印各种数据类型,比较方便外,它还有一个额外的优点,就是不会抛出IOException,这样我们在编写代码的时候,就不必捕获IOException
标识符和变量
type
status
date
slug
summary
tags
category
icon
password
Property
 
所有JavaScript变量必须以唯一的名称标识,这些唯一的名称称为标识符。 构造变量名称(唯一标识符)的通用规则是:
  • 名称可包含字母、数字、下划线和美元符号
  • 名称必须以字母开头
  • 名称也可以$_开头
  • 名称对大小写敏感(y和Y是不同的变量〕
  • 保留字(比如JavaScript的关键字)无法作变量名称
 
 
 

怎么声明变量?怎么给变量赋值?

🐼 Set
type
status
date
slug
summary
tags
category
icon
password
Property
 
Map用于存储key-value的映射,对于充当key的对象,是不能重复的,并且,不但需要正确覆写equals()方法,还要正确覆写hashCode()方法。
如果只需要存储不重复的key,并不需要存储映射的value,那么就可以使用Set
Set用于存储不重复的元素集合,它主要提供以下几个方法:
  • 将元素添加进Set<E>boolean add(E e)
  • 将元素从Set<E>删除:boolean remove(Object e)
  • 判断是否包含元素:boolean contains(Object e)
Set实际上相当于只存储key、不存储value的Map
因为放入Set的元素和Map的key类似,都要正确实现equals()hashCode()方法,否则该元素无法正确地放入Set
最常用的Set实现类是HashSet,实际上,HashSet仅仅是对HashMap的一个简单封装,它的核心代码如下:
🦛 ReentrantLock
type
status
date
slug
summary
tags
category
icon
password
Property
 
 
从Java 5开始,引入了一个高级的处理并发的java.util.concurrent包,它提供了大量更高级的并发功能,能大大简化多线程程序的编写。
我们知道Java语言直接提供了synchronized关键字用于加锁,但这种锁一是很重,二是获取时必须一直等待,没有额外的尝试机制。
java.util.concurrent.locks包提供的ReentrantLock用于替代synchronized加锁,我们来看一下传统的synchronized代码:
如果用ReentrantLock替代,可以把代码改造为:
因为synchronized是Java语言层面提供的语法,所以我们不需要考虑异常,而ReentrantLock是Java代码实现的锁,我们就必须先获取锁,然后在finally中正确释放锁。
顾名思义,ReentrantLock是可重入锁,它和synchronized一样,一个线程可以多次获取同一个锁。
synchronized不同的是,ReentrantLock可以尝试获取锁:
🍂 JTree、TreeModel实现树
type
status
date
slug
summary
tags
category
icon
password
Property
 
 
树也是图形用户界面中使用非常广泛的 GUI 组件
计算机世界里的树是由一系列具有严格父子关系的节点组成的,每个节点既可以是其上一级节点的子节点,也可以是其下一级节点的父节点,因此同一个节点既可以是父节点,也可以是子节点(类似于一个人,他既是他儿子的父亲,又是他父亲的儿子)。
按照结点是否包含子结点,可以把结点分为下面两类:
普通结点:包含子结点的结点;
叶子结点:没有子结点的结点;
按照结点是否具有唯一的父结点,可以把结点分为下面两类:
根结点:没有父结点的结点,计算机中,一棵树只能有一个根结点
普通结点:具有唯一父结点的结点
使用 Swing 里的 Jtree 、 TreeModel 及其相关的辅助类可以很轻松地开发出计算机世界里的树。
 
🍂 JTable、TableModel实现表格
type
status
date
slug
summary
tags
category
icon
password
Property
 
 
表格也是GUI程序中常用的组件,表格是一个由多行、多列组成的二维显示区 。 Swing 的 JTable 以及相关类提供了这种表格支持 , 通过使用 JTable 以及相关类,程序既可以使用简单的代码创建出表格来显示二维数据,也可以开发出功能丰富的表格,还可以为表格定制各种显示外观、编辑特性 。
 

创建简单表格

使用JTable创建简单表格步骤:
  1. 创建一个一维数组,存储表格中每一列的标题
  1. 创建一个二维数组,存储表格中每一行数据,其中二维数组内部的每个一维数组,代表表格中的一行数据
  1. 根据第一步和第二步创建的一维数组和二维数组,创建JTable对象
  1. 把JTable添加到其他容器中显示
notion image
🦛 ForkJoin
type
status
date
slug
summary
tags
category
icon
password
Property
 
Java 7开始引入了一种新的Fork/Join线程池,它可以执行一种特殊的任务:把一个大任务拆成多个小任务并行执行。
我们举个例子:如果要计算一个超大数组的和,最简单的做法是用一个循环在一个线程内完成:
notion image
还有一种方法,可以把数组拆成两部分,分别计算,最后加起来就是最终结果,这样可以用两个线程并行执行:
notion image
如果拆成两部分还是很大,我们还可以继续拆,用4个线程并行执行:
notion image
这就是Fork/Join任务的原理:判断一个任务是否足够小,如果是,直接计算,否则,就分拆成几个小任务分别计算。这个过程可以反复“裂变”成一系列小任务。
我们来看如何使用Fork/Join对大数据进行并行求和:
观察上述代码的执行过程,一个大的计算任务0~2000首先分裂为两个小任务0~1000和1000~2000,这两个小任务仍然太大,继续分裂为更小的0~500,500~1000,1000~1500,1500~2000,最后,计算结果被依次合并,得到最终结果。