lamdba streamAPI
什么是stream
Stream是用来处理一组数组
、集合
的API
使用它的原因有两个:
- 代码简洁函数式变成写出的代码简洁且意图明确,使用stream接口让你从此告别for循环。
- 多核友好,JAVA函数式编程使得编写并行程序从未如此简单,你需要的全部就是调用一下paralle()方法。
stream的特性
- 不是数据结构,没有内部存储
- 不支持索引访问
- 延迟计算(在最终操作之前,中间操作代码不会实际执行)
- 支持并行
- 很容易生成数组或集合(List,Set)
- 支持过滤,查找,转换,汇总,聚合等操作
stream的运行机制
Stream分为 源source =>
中间操作=>
终止操作
流的源可以是一个数组、一个集合、一个生成器方法,一个I/O通道等等。
一个流可以有零个和或者多个中间操作,每一个中间操作都会返回一个新的流,供下一个操作使用。一个流只会有一个终止操作
Stream只有遇到终止操作,它的源才开始执行遍历操作
Stream的创建(source)
1、通过数组
2、通过集合来
3、通过Stream.generate方法来创建
4、通过Stream.iterate方法来创建
5、其他API创建
/**
* 通过数组方式
*/
static void gen1(){
String[] strs={"a","b","c","d"};
Stream<String> stream = Stream.of(strs);
//实例方法的引用
stream.forEach(System.out::println);
}
/**
* 通过集合的方式
*/
static void gen2(){
List<String> list= Arrays.asList("a","b","c","d");
Stream<String> stream = list.stream();
stream.forEach(System.out::println);
}
/**
* generate()方法生成流会有无限长度,因此需要limit(10)限制
*/
static void gen3(){
Stream<Integer> stream = Stream.generate(() -> 1);
stream.limit(10).forEach(System.out::println);
}
/**
* iterate 迭代器的方式,同样需要限制长度,不然会无限增长
*/
static void gen4(){
Stream<Integer> stream = Stream.iterate(1, integer -> integer+1);
stream.limit(10).forEach(System.out::println);
}
/**
* 其他生成方式 IntStream也是流
*/
static void gen5(){
String str="asfghg";
IntStream chars = str.chars();
chars.forEach(System.out::println);
}
Stream的中间操作
过滤 filter
去重 distinct
排序 sorted
截取 limit、skip
转换 map/flatMap
其他 peek
public static void main(String[] args) {
List<Integer> Intlist=Arrays.asList(1,2,3,4,5,6,8);
List<String> Stringlist = Arrays.asList("c#", "java", "python", "scala");
/**
* 如果返回对象是一个stream对象,就以为着是一个中间操作
*/
//获取到集合中的偶数值
Intlist.stream().filter(integer -> integer%2==0).forEach(System.out::println);
//获取到集合中偶数的个数
long count = Intlist.stream().filter(integer -> integer % 2 == 0).count();
//获取到集合中偶数的和 (sum方法是 IntStream 的方法,因此需要mapToInt方法把Stream对象转换为IntStream对象)
int sum = Intlist.stream().filter(integer -> integer % 2 == 0).mapToInt(x -> x).sum();
//获取最大值
Optional<Integer> max = Intlist.stream().max((a, b) -> a - b);
Integer integer = max.get();
System.out.println(integer);
//获取最小值
Integer integer1 = Intlist.stream().min((a, b) -> a - b).get();
System.out.println(integer1);
//获取符合条件元素的第一个元素
Optional<Integer> first = Intlist.stream().filter(x -> x % 2 == 0).findFirst();
System.out.println(first.get());
//通过排序的方式取到最大值和最小值
/**
* sorted()方法不传递参数为自然排序,传递参数表示自定义比较器
*/
Optional<Integer> minOptional = Intlist.stream().sorted().findFirst();
Integer min = minOptional.get();
System.out.println(min);
Optional<Integer> maxOptional = Intlist.stream().sorted().sorted((a, b) -> b - a).findFirst();
Integer maxx = maxOptional.get();
System.out.println(maxx);
//字符串排序并打印
Stringlist.stream().sorted().forEach(System.out::println);
//字符串按照长度排序
Stringlist.stream().sorted((s1, s2) -> s1.length()-s2.length()).forEach(System.out::println);
//使用收集器的方式把过滤后的元素转换成list
List<Integer> collect = Intlist.stream().filter(a -> a % 2 == 0).collect(Collectors.toList());
//去重操作
Arrays.asList(2,2,3,3,6,7).stream().distinct().forEach(System.out::println);
Arrays.asList(2,2,3,3,6,7).stream().collect(Collectors.toSet()).forEach(System.out::println);
//打印20-30的数字
Stream.iterate(1,i->i+1).skip(20).limit(10).forEach(System.out::println);
//把字符串转数字并计算和
String str="11,22,33,44,55";
System.out.println(Stream.of(str.split(",")).mapToInt(value -> Integer.parseInt(value)).sum());
//方法引用的方式
System.out.println(Stream.of(str.split(",")).mapToInt(Integer::parseInt).sum());
//使用stream流 自定义一组对象
Stringlist.stream().map(string -> new Persion(string)).forEach(System.out::println);
Stringlist.stream().map(Persion::new).forEach(System.out::println);
Stringlist.stream().map(string -> Persion.build(string)).forEach(System.out::println);
Stringlist.stream().map(Persion::build).forEach(System.out::println);
//把字符串转数字并计算和 并 打印
int sum1 = Stream.of(str.split(",")).peek(System.out::println).mapToInt(Integer::parseInt).sum();
System.out.println(sum1);
}
Stream的终止操作
循环: forEach
计算: min、max、count、 average
匹配: anyMatch、 allMatch、 noneMatch、 findFirst、 findAny
汇聚: reduce
收集器 :toArray collect
扩展:lamdba表达式四大接口
- Consumer:消费型接口,内有抽象方法—void accept(T t)
- Supplier:生产型接口(供给型),内有抽象方法—T get();
- Function<T, R>:函数型接口,内有抽象方法—R apply(T t)
- Predicate:断言型接口,内有抽象方法—boolean test(T t)