一:速度快
JDK8对集合底层的数据结构进行的优化
HashMap底层引入的红黑树 ,极大的优化了HashMap的性能
二:代码少(引入了Lambda表达式)
Lambda是一个匿名函数,lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。
注意:lambda必须有函数是接口的支持 (函数式接口,即只有一个方法的接口)
lambda表达式的几种写法
总体写法:
左边:参数
右边:lambda体 即lamdba表达式所需要执行功能
(1)一个参数,无返回值
(参数)->所需执行的操作;
(e)->System.out.println();
(2)无参数,无返回值
()->所需执行的参数
()->System.out.println();
System.out.println();//省略参数的写法
(3)有两个以上参数,并且又返回值
(参数列表)->{
执行语句
return 返回值};
若只有一条语句 return 和大括号可以不写
四大内置接口
(1)消费型
Consumer<String> consumer = e -> System.out.println(e);
consumer.accept("我是tubo");
(2)断言型
Predicate<String> flag = e -> e.equals("");
flag.test("");
(3)供给型
Supplier<String> supplier = () -> "";
supplier.get();
(4)函数型
Function<String, String> function = (e) -> "我是" + e;
function.apply("tubo");
方法引用
若lambda体中有方法已经实现,我们可以使用"方法引用"
三种语法格式
(1)
对象::实例方法名
ArrayList<Object> arrayList = new ArrayList<>();
arrayList.forEach(System.out::println);
类::静态方法名
Comparator<Integer> comparator=Integer::compare;
类::实例方法名
BiPredicate<String, String> bpBiPredicate=String::equals;
注意:
1.Lambda体中调用方法的参数列表为返回值类型.要与函数式接口中的抽象方法的函数列表和返回值保持一致
2.若Lambda 参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method
构造器引用
ClassName::method
注意需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致
三:引入了Stream API
Stream(流)是用来操作数据源(数组,集合等)所生成的元素序列。
注意事项:
1:Stream自己不会存储元素.
2:Stream 不会改变源对象.相反,他们会返回一个持有结果的新的Stream
3:Stream 操作时延迟执行.这意味着他们会等到需要结果的时候才执行.
1.创建Stream的几种方法
(1)可以通过Collection系列集合提供的stream()或paralleStream()
List<String> arrayList = new ArrayList<>();
Stream<String> stream = arrayList.stream();
(2)通过Arrays中的静态方法stream()获取数组流
int[] arr=new int[10];
IntStream stream2 = Arrays.stream(arr);
(3)通过Stream类中的静态方法of()
Stream<String> stream3 = Stream.of("aa");
(4)创建无限流
Stream<Integer> stream4 = Stream.iterate(0, x->x+2);
2.Stream的中间操作
stream的中间操作可以连接起来形成一个流水线,除非流水线触发终止操作,否则中间操作不会执行,而在终止操作时一次全部处理,称为惰性求值
筛选与切片
List<String> arrayList = new ArrayList<>();
arrayList.add("111");
arrayList.add("2");
arrayList.add("aa");
arrayList.add(" ");
arrayList.add(" ");
Stream<String> stream = arrayList.stream();
filter 方法用于过滤元素。以下代码片段使用 filter 方法过滤出长度不为1的字符串:
stream.filter(e -> e.length() != 1).forEach(System.out::println);
limit 方法用于获取指定数量的流。
stream.limit(1).forEach(System.out::printf);
skip 方法用于获取跳过指定数量的流,若流中不足,则返回一个流
stream.skip(1).forEach(System.out::printf);
distinct 用于去除重复对象
stream.distinct().forEach(System.out::printf);
映射
map 方法用于映射每个元素到对应的结果,
List<String> arrayList = new ArrayList<>();
arrayList.add("aa");
arrayList.add("bb");
arrayList.add("cc");
arrayList.stream().map(e->e.toUpperCase()).forEach(System.out::println);
排序
sorted
sorted 方法用于对流进行排序
3.Stream的终止操作
allMatch(Predicate p) 检查是否匹配所有元素
anyMatch( (Predicate p) ) 检查是否至少匹配一个元素
noneMatch(Predicate p) 检查是否没有匹配所有元素
findFirst() 返回第一个元素
findAny() 返回当前流中的任意元素
count() 返回流中元素总数
max(Comparator c c) ) 返回流中最大值
min(Comparator c c) ) 返回流中最小值
forEach(Consumer c c) ) 内部迭代 ( (用 使用 Collection 接口需要用户去做迭代,称为 外部迭代 。相反, Stream API 使用内部迭代 —— 它帮你把迭代做了) )
规约
reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。 返回 T
reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。 返回 Optional<T>
收集
collect(Collector c) 将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法。
Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、 Set、 Map)。但是 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例
toList
List<T> 把流中元素收集到List
toSet
Set<T> 把流中元素收集到Set
toCollection
Collection<T> 把流中元素收集到创建的集合
counting
Long 计算流中元素的个数
summingInt
Integer 对流中元素的整数属性求和
averagingInt
Double 计算流中元素Integer属性的平均值
summarizingInt
IntSummaryStatistics 收集流中Integer属性的统计值。如:平均值
joining
String 连接流中每个字符串
maxBy
Optional<T> 根据比较器选择最大值
minBy
Optional<T> 根据比较器选择最小值
reducing
归约产生的类型 从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值
collectingAndThen
转换函数返回的类型 包裹另一个收集器,对其结果转换函数
groupingBy
Map<K, List<T>> 根据某属性值对流分组,属性为K,结果为V
partitioningBy
Map<Boolean, List<T>> 根据true或false进行分区