数据渠道,主要是操作数据源(集合,数组等),进行中间操作,获取结果
【特点】:
A:Stream本身不存储任何的元素。
B:Stream只是提供中间操作,返回新的Stream中有结果。而对数据源没有任何的改变。
C:Stream的中间操作是延迟的,直到遇到终端操作。
【步骤】:
step1:获取Stream对象
step2:提供中间操作链
step3:终端操作
【心得】:
注意每一步所返回的类型,调用Stream的方法,来达到想要返回的结果,比如:
User user = new User();
user.setName("张三");
User user1 = new User();
user1.setName("李四");
List<User> list = new ArrayList<>();
list.add(user);
list.add(user1);
//抽出name,成List
List<String> rList = list.stream() //step1.返回Stream
.map((x)->x.getName()) //step2.返回Stream
.collect(Collectors.toList()); //Step3.返回List
System.out.println(rList);
//输出:[张三, 李四]
【针对于集合】:
//1.通过Collection接口中的stream()和parallelStream()
List<String> l1 = new ArrayList<>();
Stream<String> stream1 = l1.stream()
【针对于数组】:
Arrays.stream([])-->IntStream/DoubleStream.../Stream
//2.从数组上获取Stream流。Arrays工具类
int[] arr = new int[10];
IntStream stream2 = Arrays.stream(arr);
【针对于数值】:
Stream.of(T t)
Stream.of(T...t)
//3.通过Stream流的of方法获取
Stream<String> stream4 = Stream.of("aa","bb","cc");
【无限流-迭代iterate()】:
Stream.iterate(T seed,UnaryOpertor)
第一个参数:seed,种子,起始值
第二个参数:UnaryOperator,函数式接口,继承Function
Stream<Integer> stream5=Stream.iterate(0, (x)->x+2);
//相当于int x = 0;x += 2;
【无限流-生成generate()】:
Stream.generate(Supplier); //Supplier:供给型函数式接口
Stream<Double> stream6 = Stream.generate(()->Math.random());
“惰性求值”:终端操作时,会一次性处理全部中间操作
5-1. 筛选与切片
方法 | 描述 |
---|---|
filter(Predicate p) | 接收Lambda,从流中排除某些元素 |
distinct() | 筛选,通过流所生成元素的hashCode()和equals()去重 |
limit(long n) | 截断流,使元素不超过给定数量n个 |
skip(long n) | 跳过n个前面的元素,返回n后面的元素 |
【筛选与切片-filter】:
List<Integer> list = Arrays.asList(12,34,56,45,66,66);
Stream<Integer> liststr = list.stream().filter((x)->x>40);
liststr.forEach(System.out::println); //终端操作,下文介绍
//list.stream()获取stream对象,然后filter操作,x为stream每个元素,然后返回>40的元素
//输出56,45,66,66
【筛选与切片-distinct】:
List<Integer> list = Arrays.asList(12,34,56,45,66,66);
Stream<Integer> liststr = list.stream().filter((x)->x>40).distinct();
liststr.forEach(System.out::println);
//输出56,45,66
【筛选与切片-limit】:
List<Integer> list = Arrays.asList(12,34,56,45,66,66);
Stream<Integer> liststr = list.stream().filter((x)->x>40).limit(2);
liststr.forEach(System.out::println);
//输出56,45
【筛选与切片-skip】:
List<Integer> list = Arrays.asList(12,34,56,45,66,66);
Stream<Integer> liststr = list.stream().filter((x)->x>40).skip(2);
liststr.forEach(System.out::println);
//输出66,66
5-2. 映射:
流中的每一个元素,都应用到参数Lambda表达式上,获取对应的内容,返回新的stream对象。
方法 | 描述 |
---|---|
map(Funtion |
接收一个函数作为参数,该函数被应用到每个元素,并将其映射成一个新的元素 |
mapToInt(ToIntFunction |
接收一个函数作为参数,该函数被应用到每个元素,产生新的IntStream |
flagMap(Functiom |
接收一个函数作为参数,把流中每个值都换成另一个流,然后把所有流连接成一个流 |
【映射-map】:
. map(Function
List<String> list = Arrays.asList("aa","bb","cc");
Stream<String> str = list.stream().map((s)->s.toUpperCase());
str.forEach(System.out::println);
//map()参数为函数式接口对象,接口方法.accpet(T),返回R,实现方法箭头右侧
//流中的每一个元素都应用到Lambda表达式,并映射成新的元素
//"aa"应用Lambda后映射成"AA"
//输出AA,BB,CC
. flatMap(Function
public static void main(String[] args) {
List<String> list = Arrays.asList("aa","bb","cc");
Stream<Character> stream = list.stream().flatMap((s)->getCharacter(s));
//Stream> streamStream = list.stream()
// .map((s) -> getCharacter(s));
stream.forEach(System.out::println);
}
public static Stream<Character> getCharacter(String str){
//str="aaa";
List<Character> list = new ArrayList<>();
for(int i=0;i<str.length();i++){
list.add(str.charAt(i));
}
return list.stream();
}
//getCharacter方法返回Stream,.map返回的使嵌套的Stream>对象
//.flatMap返回的则是连接一起的stream对象
//.flatMap参数需要返回一个Stream对象
5-3. 排序:
方法 | 描述 |
---|---|
sorted() | 产生一个新的流,其中按自然顺序 |
sorted(Comparator com) | 产生一个新的流,其中按比较器顺序比较 |
【排序-sorted】:
.sorted():自然排序,流中的对象,实现Comparable
List<Integer> list = Arrays.asList(56,45,66,66);
Stream<Integer> liststr = list.stream().sorted();
liststr.forEach((s)->System.out.print(" "+s));
//输出56,45,66,66
【排序-sorted(Comparator)】:
.sorted(Comparator),自定义排序
List<Integer> list = Arrays.asList(12,34,56,45,66,66);
Stream<Integer> liststr = list.stream().sorted((e1,e2)->{
if (e1<e2) {
return 0;
}
return -1;
});
liststr.forEach((s)->System.out.print(" "+s));
} // 66 66 56 45 34 12
6-1. 归约(reduce):可以将流中元素反复结合起来,得到一个值。
reduce(BinaryOperator)、reduce(T,BinaryOperator)
第一个参数:T identity,用于起始值
第二个参数:BinaryOperator,二元操作,函数式接口
public void test1(){
List<Integer> list = Arrays.asList(1,2,3,4,5,6);
Integer sum = list.stream().reduce(0,(x,y)->x+y);
System.out.println(sum);
}
//第一次:x-->0 y-->1
//第二次:x-->1 y-->2
//第三次:x-->3 y-->3
//输出:21
6-2. 收集(collect):
collect(Collector),将流转换为其他形式。
接收一个Collector接口的实现,用于给Stream中元素做汇总的方法需要参数:Collector收集器(接口)
该接口对象,可以使用Collectors提供的静态方法获取(比如Collectors.toList())
【集合】:
List<Integer> list = Arrays.asList(12,34,56,45,66,66);
List<Integer> coList = list.stream().filter((x)->x>40).collect(Collectors.toList());
System.out.println(coList);
//输出: [56, 45, 66, 66]
//toSet()会按规则去重
List<Integer> list = Arrays.asList(12,34,56,45,66,66);
Set<Integer> coSet = list.stream().filter((x)->x>40).collect(Collectors.toSet());
System.out.println(coSet);
//输出: [66, 56, 45]
【统计-counting】:
List<Integer> list = Arrays.asList(12,34,56,45,66,66);
Long cocou = list.stream().filter((x)->x>40).collect(Collectors.counting());
System.out.println(cocou); //输出:4
【统计-summing】:
Collectors.summingDouble(ToDoubleFunction)
Collectors.summingInt(ToIntFunction)
Collectors.summingLong(ToLongFunction)
List<Integer> list = Arrays.asList(12,34,56,45,66,66);
Integer collect = list.stream().filter((x)->x>40)
.collect(Collectors.summingInt((e)->e)); //
System.out.println(collect); //输出:233
【统计-averageDouble】:
List<Integer> list = Arrays.asList(12,34,56,45,66,66);
Double collect = list.stream().filter((x)->x>40)
.collect(Collectors.averagingDouble((e)->e)); //平均值
System.out.println(collect); //输出: 58.25
【统计-maxBy】:根据比较器选择最大值
【统计-minBy】:根据比较器选择最小值
List<Integer> list = Arrays.asList(12,34,56,45,66,66);
Optional<Integer> collect = list.stream()
.collect(Collectors.maxBy((e1,e2)->e1-e2));
System.out.println(collect.get());//输出: 66
【分组】:Collectors.groupingBy(Function)
【匹配与查找】:
allMatch()–>是否匹配所有
anyMatch()–>是否匹配任意一个
noneMatch()–>是否都不匹配
findFirst()–>
findAny()
count()–>获取流中元素个数
max(Comparator)–>
min(Comparator)
【String/StringBuffer循环赋值】:
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer();
Stream<StringBuffer> limit = Stream.generate(() -> stringBuffer.append("0")).limit(51);
System.out.println(limit.count()); //51
System.out.println(stringBuffer.toString());//拼接的51个0
}