A.泛型定义
在JAVA8中经常用泛型来表示各种元素。
在JAVA中它是一个偽泛型,因为JVM层字节码层没有泛型的概念,泛型的代码被编译成字节码后,对应的泛型操作就消失了,这叫擦除法。
使用泛型元素之前会对该元素的类型做一个检查,才能继续使用。只多了检查这一步,其他的没有变化都一样。
但需要注意的是,如果我们去获取泛型类型这种类型定义,通过反射的方式拿到Class对象上的一些具体的元数据,是能拿到一些泛型相关的信息的。
取巧用法:Java中泛型可以T extends 接口1&接口2&接口3
在其他很多语言中,泛型是个真正存在的类型,
例如:
- List
listUser; - List
listAppUser;
JAVA中这两个list对象是完全没有关系的。
其他具体泛型的语言中,listUser可以派生出子类型listAppUser,或者认为listAppUser有父类型listUser。这些类型是有层次关系真实存在的。
B.Lambda
1.表达式
1-1.定义:
(parameters) -> expression
(parameters) -> {statements;}
1-2.种类举例:
// 1. 不需要参数,返回值为 5
() -> 5
int m() { return 5;}
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
int m(int x) { return 2 * x;}
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
int m(int x,int y) { return x - y;}
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
int m(int x,int y) { return x + y;}
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
void m(String s) { System.out.print(s); }
1-3.Java7/Java8演化实例
原始接口:
interface MyLambdaInterface {
void doSomeShit(String s);
}
Java7实现接口:
class MyLambdaInterfaceImpl implements MyLambdaInterface{
@Override
void doSomeShit(String s) {
System.out.println(s);
}
}
Java8实现接口(没啥用):
class Main {
public static void main() {
MyLambdaInterface myLambda = (s) -> System.out.println(s);
}
}
Java7使用接口:
class Main {
public static void main() {
MyLambdaInterface myLambda = new MyLambdaInterfaceImpl();
enact(myLambda, "test");
}
public static void enact(MyLambdaInterface lamdaInterface, String s) {
lamdaInterface.doSomeShit(s);
}
}
Java8使用接口(不需要有显示实现接口的壳MyLambdaInterfaceImpl):
class Main {
public static void main() {
MyLambdaInterface myLambda = (s) -> System.out.println(s);
enact(s -> System.out.println(s), "test");
}
public static void enact(MyLambdaInterface lamdaInterface, String s) {
lamdaInterface.doSomeShit(s);
}
}
2.函数式
核心注解:
核心接口:
- Predicate
有参数、条件判断 - Function
有参数、有返回值 - Consumer
无返回值 - Supplier
无参数、有返回值
3.EXAMPLE
C.Stream
1.定义
Stream(流)是一个来自数据源的元素队列并支持聚合操作
•元素:特定类型的对象,形成一个队列。 Java 中的 Stream 并不会存储元素,而是按需计算。
•数据源:流的来源。可以是集合,数组,I/O channel,产生器 generator 等。
•聚合操作:类似 SQL 语句一样的操作,比如 filter, map, reduce, find, match, sorted 等。
和以前的 Collection 操作不同, Stream 操作还有两个基础的特征:
•Pipelining:中间操作都会返回流对象本身。这样多个操作可以串联成一个管道,如同流式风格(fluent style)。这样做可以对操作进行优化,比如延迟执行(laziness)和短路(short-circuiting)。
•内部迭代:以前对集合遍历都是通过 Iterator 或者 For-Each 的方式,显式的在集合外部进行迭代,这叫做外 部迭代。Stream 提供了内部迭代的方式,通过访问者模式(Visitor)实现。
2.操作方法
中间操作Fluent API:继续stream
1、选择与过滤
- filter(Predicate p) 接收 Lambda , 从流中排除某些元素。
- distinct() 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素。
- limit(long maxSize) 截断流,使其元素不超过给定数量。
- skip(long n) 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。
2、映射
- map(Function f) 接收 Lambda , 将元素转换成其他形式或提取信息;接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
- mapToDouble(ToDoubleFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。
- mapToInt(ToIntFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的IntStream。
- mapToLong(ToLongFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream。
- flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接 成一个流。
3、排序
- sorted() 产生一个新流,其中按自然顺序排序
- sorted(Comparator comp) 产生一个新流,其中按比较器顺序排序
终止操作:返回
1.查找与匹配
- allMatch——检查是否匹配所有元素
- anyMatch——检查是否至少匹配一个元素
- noneMatch——检查是否没有匹配的元素
- findFirst——返回第一个元素
- findAny——返回当前流中的任意元素
- count——返回流中元素的总个数
- max——返回流中最大值
- min——返回流中最小值
2.归约
- reduce, 需要初始值(类比 Map-Reduce)
3.收集
- collect
- toList List
把流中元素收集到 List - toSet Set
把流中元素收集到 Set - toCollection Collection
把流中元素收集到创建的集合 count 计算流中元素的个数
4.迭代 forEach
- summaryStatistics 统计最大最小平均值
3.EXAMPLE
D.Lombok
巴厘岛旁边的一个小岛
1.常规注解
@Setter
@Getter
@Data // =Getter + Setter + RequiredArgsConstructor + ToString + EqualsAndHashCode
@XXXConstructor
@Builder
@ToString
@Slf4j // lombok.extern.slf4j.Slf4j
@Log // lombok.extern.java.Log
2.maven-pom依赖
3.EXAMPLE
E.Guava
1.定义
JDK基础上做增强的一个第三方工具类库。
这个库提供用于集合,缓存,支持原语,并发性,常见注解, 字符串处理,I/O 和验证的实用方法。
JDK8 里的一些新特性源于 Guava,比如Stream里的Optional。
2.maven-pom依赖
3.内容
集合[Collections]
Guava 对 JDK 集合的扩展,这是 Guava 最成熟和为人所知的部分
- 1 不可变集合:用不变的集合进行防御性编程和性能提升。
- 2 新集合类型:multisets, multimaps, tables, bidirectional maps 等
- 3 强大的集合工具类:提供 java.util.Collections 中没有的集合工具
- 4 扩展工具类:让实现和扩展集合类变得更容易,比如创建 Collection 的装饰器,或实现迭代器
缓存[Caches]
本地缓存实现,支持多种缓存过期策略
并发[Concurrency]
ListenableFuture:完成后触发回调的 Future
字符串处理[Strings]
非常有用的字符串工具,包括分割、连接、填充等操作
事件总线[EventBus]
发布-订阅模式的组件通信,进程内模块间解耦
反射[Reflection]
Guava 的 Java 反射机制工具类