延迟创建底层数组
HashMap底层添加了红黑树
Lambda表达式
@Test
public void test2(){
Comparator comparator=new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return Integer.compare((Integer) o1,(Integer) o2);
}
};
System.out.println(comparator.compare(1,2));
System.out.println("...........................");
Comparator comparator1=(Object o1,Object o2)->Integer.compare((Integer)o1,(Integer)o2);
System.out.println(comparator1.compare(5,3));
System.out.println("...........................");
Comparator<Integer> comparator2=Integer :: compare;//这样的话必须设置泛型
System.out.println(comparator2.compare(46,50));
}
无参无返回值:
()->{运行代码};
带参无返回值:
(参数类型 参数)->{对参数操作的代码};
同上:
(参数)->{对参数操作的代码};//需要用到泛型或编译器可进行类型推断
只需要一个参数时小括号可以省:
参数->{对参数操作的代码};
多个参数及多条运行语句,且有返回值:
(参数1, 参数2)->{
代码1;
代码2;
return 返回值;
};
只有一句语句时:
(参数1, 参数2)-> 运行语句;
总结
左边:列表参数类型可省略(类型推断),只有一个参数时括号可以省略
右边:Lambda体需要{}包裹,如果只有一条执行语句{}可以省略
本质上是接口(函数式接口)的实例
函数式接口
只有一个抽象方法,也可以用@FunctionalIterface注解说明该接口是函数式接口
四大核心函数式接口
Consumer:
包含方法void accept(T t),有参无返回值
Supplier:
包含方法T get(),无参有返回值
Function<T, R>:
包含方法R apply(T t),有参有返回值
Predicate:
包含方法boolean test(T t),有参有返回值(用于确定t是否满足某种约束)
方法引用与构造器引用
使用情景(方法)
将已经实现的方法传递给Lamba体时使用方法引用
使用方式:
类(或对象):: 方法名
要求接口中的抽象方法的形参列表和返回类型 与 方法引用的参数列表和返回类型一样
如:
对象 :: 非静态方法
@Test
public void test3(){
PrintStream ps=System.out;
Consumer con1=ps::println;
con1.accept("你好");
}
类 :: 静态方法
@Test
public void test3(){
Comparator<Integer> comparator=Integer::compare;
//注意泛型
System.out.println(comparator.compare(1,2));
}
类 :: 实例方法(非静态方法)//特例
Comparator<String> comparator=String::compareTo;
System.out.println(comparator.compare("1","2"));
上例等价于:
“1”.compareTo(“2”);
使用情景(构造器)
要求:函数式接口的抽象方法的形参列表与构造器的形参列表一致
抽象方法的返回值类型为构造器所属的类的类型
@Test
public void test3(){
Supplier<Person> supplier=Person::new;
System.out.println(supplier.get());
Function<String,Person> function=Person::new;
Person person= function.apply("李华");
System.out.println(person);
Function<Integer,String[]>function1=String[]::new;
String[] str=function1.apply(10);
System.out.println(str.length);
}
Stream API
Stream与Collection集合的区别:
后者是静态的、存储在内存的,
前者是有关计算的、面向CPU,通过CPU实现计算。
Stream不会改变源对象、不会存储元素、是延迟执行操作的(等到需要结果时才执行)
Stream的三个步骤:创建Stream对象、中间操作、终止操作
在终止操作之前不执行中间操作
实例化Stream接口
方法一:通过集合
List list=new ArrayList();
list.add(1);
list.add(3);
list.add(4);
Stream<Integer> stream=list.stream();//顺序流
Stream<Integer> parallelStream=list.parallelStream();//并行流
方法二:通过数组
int[] nums={1,2,3,4,5};
IntStream stream= Arrays.stream(nums);
方法三:通过Stream的of()
Stream<Integer> stream= Stream.of(1,2,3,4,5);
方法四:创建无限流
使用迭代器(Stream.iterate(起始数组,递归公式).limit(上限).forEach(操作))、生成器(Stream.generate…(同上))
中间操作
筛选与切片
方法:
filter(Predicate p) 接收Lamba,从中排除某些元素
Stream<Integer> stream= Stream.of(1,2,3,4,5);
stream.filter(integer->integer>3).forEach(System.out::println);//打印大于3的数
limit(long n) 输出前n条数据
Stream<Integer> stream= Stream.of(1,2,3,4,5);
stream.limit(3).forEach(System.out::println);//输出前三条数据
skip(long n)跳过前n条数据
Stream<Integer> stream= Stream.of(1,2,3,4,5);
stream.skip(3).forEach(System.out::println);//跳过前三个数据
distinct()去重
Stream<Integer> stream= Stream.of(1,2,3,4,5,7,5,4);
stream.distinct().forEach(System.out::println);//去重
映射
方法:
map(Function f)接收一个函数作为参数,将元素转换为其他形式或提取信息(相当于list.add()形式为{数据一,数据二,Stream1,Stream2})
Stream<Integer> stream= Stream.of(1,2,3,4,5,7,5,4);
stream.map(integer -> integer*2).forEach(System.out::println);
flatMap(Function f)接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有的流连接成同一个流(相当于list.addAll(),里面只有数据)
list.stream().flatMap(StreamAPITest::getIntegerStream).forEach(System.out::println);//flatMap直接拆散每个流来遍历
map与flatMap的区别:
@Test
public void test(){
List<List> list=new ArrayList();
List list1=new ArrayList();
List list2=new ArrayList();
list1.add(1);
list1.add(2);
list2.add(3);
list2.add(4);
list.add(list1);
list.add(list2);
Stream<Stream> stream = list.stream().map(StreamAPITest::getIntegerStream);
stream.forEach(s->{
s.forEach(System.out::println);
});//map返回的是一整个流(注意Stream<Stream>)
}
public static Stream getIntegerStream(List list){
return list.stream();
}
@Test
public void test(){
List<List> list=new ArrayList();
List list1=new ArrayList();
List list2=new ArrayList();
list1.add(1);
list1.add(2);
list2.add(3);
list2.add(4);
list.add(list1);
list.add(list2);
list.stream().flatMap(StreamAPITest::getIntegerStream).forEach(System.out::println);//flatMap直接拆散每个流来遍历
}
public static Stream getIntegerStream(List list){
return list.stream();
}
排序
sorted()自然排序/sorted(Comparator comparator)定制排序
public void test(){
List list1=new ArrayList();
list1.add(1);
list1.add(2);
list1.stream().sorted().forEach(System.out::println);
}
终止操作
匹配与查找
方法:
allMatch(Predicate p)检查是否全部元素符合要求
boolean b = list1.stream().allMatch(integer -> integer > 0);
System.out.println(b);
anyMatch(Predicate p)检查是否存在一个元素符合要求
boolean b = list1.stream().anyMatch(integer -> integer > 0);
System.out.println(b);
noneMatch(Predicate p)检查是否全部元素都不符合要求
(同上)
findFirst返回第一个元素
Optional<Integer> first = list1.stream().findFirst();
System.out.println(first.get());
findAny返回当前流中随机元素
Optional<Integer> first = list1.parallelStream().findAny();//注意使用并行流
System.out.println(first.get());
max(Comparator c)返回流中最大值
count返回个数
long count = list1.stream().filter(integer -> integer < 1).count();
System.out.println(count);
forEach(Consumer c)内部迭代(iterator是外部迭代)
归约
方法:
reduce(T identity, BinaryOperator)将流中数据反复结合起来,得到一个值,返回结果 identity为初始值,BinaryOperator为三元函数(a=b?c)
Integer reduce = list1.stream().reduce(0, Integer::sum);
收集
方法:
collect(Collector c)将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法。(可以调用Collectors的方法)
List list=new ArrayList();
list.add(1);
list.add(2);
list.add(3);
Object collect = list.stream().filter(x -> (Integer) x < 2).collect(Collectors.toList());
Collectors:
toList \ toSet \ toCollection \ conuting \ summingInt(求和) \ averagingInt(平均数) \ summarizingInt(收集流中Integer的统计值如平均值)
Optional类
Optimal类是一个容器类,可以保存的值,可以存储null的同时调用isPresent()方法查看是否是null
Optional.of(T t)创建一个Optional对象,t必须非空
Optional.empty()创建一个空的Optional对象
Optional.ofNullable(T t) t可以为空
get()若包含非空对象返回该对象,否则返回异常
orElse(T other)若包含非空对象返回该对象,否则返回other
orElseGet(Supplier<? extends T> other) 若包含非空对象返回该对象,否则返回由Supplier接口实现的对象即内容为空的新对象
orElseThrow(Supplier<? extends T> exceptionSupplier)若包含非空对象返回该对象,否则返回Supplier接口提供的异常