Java核心技术卷二
#目前以了解为主,待到要用的时候再去细究
流库
流提供一种可以在比集合更高的概念级别上指定计算的数据视图。通过使用流,我们可以说明想要完成什么任务,而不是说明如何实现。将实现留给具体的方法,专注于顶层逻辑。
流的特性
流不存储元素、流的操作不会修改数据源。
流的创建
Collection接口中的stream方法可以将任何集合转换为一个流;静态方法Stream.of,通过可变长参数将一个数组构建为一个流有任意数量引元的流。
流的转换
产生一个新的流,流的元素派生自另一个流中的流
filter
该转换产生的流的元素与某种条件相匹配,也就是说是从原始流中返回lambda匹配的元素组成的新流,元素未变化。
map
按照lambda转换流中的每一个元素,用新元素组成新的流。
flatmap
与map类似,但唯一不同的是这个转换之后的流的每一个元素都是一个原始流类型的流。
distinct
原始流中的元素按照同样的顺序剔除重复元素后产生的新流。
peek
产生一个一摸一样的新流,元素与原始流相同,但在赋值的时候,每个元素都会调用相同lambda,方便调试。
sorted
流的排序,有用于操作Comparable元素的流的方法以及可以接收Comparator的方法。返回原始流排序后产生的新流。
流的抽取与连接
抽取
limit
指定结束的坐标。
skip
指定开始的坐标。
连接
concat
将两个流连接起来。
约简
将流约简为可以在程序中使用的非流值。定义的方法返回的值基本都是一种包装了类型T或者没有包装任何对象的包装器对象,以此来代替类型T的引用,使得约简操作在值不存在且未作完备测试时不抛出空指针异常。
max min
返回由比较器定义的排序规则产生的最大元素、最小元素。
findFirst findAny
返回流中的第一个元素和任意一个元素。
anyMatch allMatch noneMatch
当这个流中的任意元素、所有元素、没有元素匹配给定断言时返回true。
Optional的使用
产生替代值来代替空的Optional对象
optionalValue.orElse(T other);
#用other代替空
optionalValue.orElseGet(()->{});
#调用lambda的结果代替空
仅在Optional对象值不为空的时候执行操作
optionalValue.ifPresent(v->{});
#值存在的时候执行lambda
optionalValue.ifPresent(results::add);
#值存在的情况下将值添加到某个集中
获取包装器的值
get方法在Optional值存在的情况下获得其中包装的元素,不存在的情况下抛出NoSuchElementException对象。
收集结果
查看流中的元素。将流中元素收集到集或者映射表
stream.forEach(函数);
#调用该方法,将某个函数运用于任意顺序遍历的每个元素
stream.forEachOrdered(函数);
#同上,但以流中顺序处理
stream.toArray();
#返回一个Object[]数组
stream.collect(Colletors.toList());
stream.collect(Collectors.toSet());
#流的collect方法接收一个实现了Collector接口的实例,同时Collercors类提供了大量用于生成公共收集器的工厂方法,可以快速将流收集到列表或者集合中去
stream.cllect(Collectors.toCollention(TreeSet::new);
`TreeSet::new表示向方法传入一个构造器TreeSet的引用`
#控制获得的集的种类
stream.collect(Colletcors.joining());
#将流中元素逐个增加到字符串当中,也可以在joining方法参数中控制连接是否需要分隔符号
stream.map(Object::toString).collect(Collectors.joining());
#先将流中其它对象转换为字符串,然后再将其连接起来(可控制分割符)
stream.iterator();
#产生一个可以获取当前流中各个元素的迭代器
stream.collect(Collectors.toMap(Object::getId,Function.identity()));
#Function.identity()函数返回输入值。(起到中转的作用)
将相同特性的值群汇聚成组
stream.collect(Collectors.groupingBy(分类函数));
#分类函数返回的是当前元素所属的类别,也就是按值分配,每个值都是一个列表
stream.collect(Colletcors.groupingBy(分类函数,下游收集器);
#
stream.collect(Collectors.partitioningBy(()->{})).get(true);
#将流中元素分为lambda返回为false的与true的两部分,并获取true的那一部分,适合分类函数返回值为boolean的函数。
基本类型流
在使用包装器对基本类型进行处理时,效率较低。流库中具有专门的基本类型流,其中IntStream存储short、char、byte、boolean,DoubleStream存储float、double,LongStream存储long。
对象流与基本类型流的转换
mapToInt、mapToLong、mapToDouble将对象流的元素对象按照传入的方法(方法返回对应的基本类型)转换为基本类流。
stream.mapToInt(String::length);
:将字符串流转换为每个元素字符串对应的长度的整型基本类流
基本类型流转换为对象流
intStream.boxed()
待补充
输入与输出
输入、输出流与之前的流库没有任何关系,其中抽象类InputStream、OutputStream是I/O类层次结构的基础。
小知识点
- 关闭一个输出流的同时会冲刷用于该输出流的缓存区,其中的所有字节都将被送出
- 面向字节的流不便于处理Unicode形式存储的信息,因为其是基于byte的
- 对象输出流中每个对象都是用一个序列号保存的,每一个对象引用都关联一个序列号,但序列号区别于内存地址,序列号的本质是对象的所有数据
- 通过序列化机制可以达到一个对象的深拷贝:直接将对象序列化到输出流,再读回来
- Paths类中默认的文件系统路径分隔符Unix是/,Windows是\
- Path、Files类封装了在用户机器上处理文件系统所需要的所有功能
待补充
正则表达式
XML
网络
数据库编程
注解
- 注解是由注解接口来定义的
modifiers @interface AnnotationName
{
elementDeclaration1
elementDeclaration2
}
- 所有的注解接口都隐式地扩展自.Annotation常规接口
- 注解接口无法被扩展
- 不用提供实现了注解接口的类
- 注解元素的类型可以为基本类型、String、Class、enum、注解类型以及这些类型的数组
- 注解的格式为
@AnnotationName(elementName1 = value1,elementName2 = value2)
,但如果不需要知道元素值或使用默认值则@AnnotationName
去掉括号 - 注解是由编译器计算而来的,所以所有元素值都必须是编译器常量
安全
java刚问世时,由于其能够安全的运行通过因特网传播的各种applet而受欢迎,java提供确保安全的机制如下
- 语言设计特性,如对数组的边界进行检查,无不受检查的类型转换,无指针算法
- 访问控制机制,用于控制代码能够执行的操作,比如文件访问,网络访问
- 代码签名,通过该特性,代码的作者可以用标准的加密算法来认证java代码,这样代码的使用者就能够准确的知道谁创建了该代码,以及代码被标识后是否被修改过
- 类加载器可以在将类加载到虚拟机中的时候检查类的完整性
- 安全管理器类控制代码运行
- java.security包提供的加密算法用来进行代码标识和用户身份认证
AWT
- 可以容易的绘制各式各样的形状
- 可以控制绘制形状的笔画,控制跟踪形状边界的绘图笔
- 可以用单色、变化的色调、重复的模式来填充各种形状
- 可以使用变换法,对各种形状进行移动、缩放、旋转和拉伸
- 可以对形状进行剪切,将其限制在任意的区域内
- 可以选择各种组合规则,来描述如何将新形状的像素与现有的像素组合起来
- 可以提供绘制图形提示,以便在速度和绘图质量之间实现平衡
本地方法
- Java本地接口JNI是java用于和本地C代码进行互操作的API
- C、C++编写的代码没有对通过使用无效指针所造成的内存覆写提供保护,所以编写本地代码容易破坏程序,感染操作系统