JAVASE8流库Stream学习总结(一)
什么是流
JAVASE8提供了一种叫做流的工具,他是一种在集合更高的概念级别的数据视图。在我看来,他是一种升级版的iterator(迭代器),但和
迭代器不同的是,流关注的是“做什么”,而不是“怎么做”。在集合的迭代器中,我们首先要获取迭代器,然后用迭代器对集合中的元素
进行遍历,顺便进行操作,而用流,我们只需要说明我们要干什么,而不是怎么去实现它
流的特点:
- 不存储任何元素
- 不改变数据源
- 惰性执行(意味着需要结果时才会执行某个操作)
流的工作流程:
- 流的建立
- 流的转换
- 流的聚合
下面重点记录流的使用
流的创建:
1、建立流(获取流)
- 对于实现了Collection接口的集合,可以使用其stream()方法创建流对象
- 对于一个数组对象,那么可以用Sream.of()创建流
- 使用Array.stram(array,from,to)创建流,from是开始的索引(包括该索引),to是结束的索引位置(不包括该索引)
- 特殊:如果要创建一个不包括任何元素的空流,可以用Stream.empty()方法
- 创建无限流
重点记录一下怎么创建和理解无限流
1、Stream.generate(),该方法接收一个Supplier<T>接口的对象
例如:
这个show()方法接收title用于说明和一个stream对象用于输出10个或10个一下的元素(不管stream是有限还是无限的集合)
public static <T> void show(String title,Stream<T> stream) {
final int size=10;
List<T> list=stream.limit(size).collect(Collectors.toList());
System.out.println(title+":");
for(int i=0;i<list.size();i++) {
if(i>0) System.out.print(",");
if(i<size) System.out.print(list.get(i));
else
System.out.print("...");
}
System.out.println();
}
main函数中:
Stream<String> stream2=Stream.generate(()->"Echo");
show("echo", stream2);
Stream<String> stream2=Stream.generate(()->"Echo");
show("echo", stream2);
输出:
echo:
Echo,Echo,Echo,Echo,Echo,Echo,Echo,Echo,Echo,Echo
这里使用了lambda表达式,这种表达式实际上是一种匿名方法,只不过该方法的只有一行代码,下面是使用方法
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
举例子来说,上面的第一个表达式如果用函数方法写,则为:
public int f(){
return 5;
}
第二个则是:
public int f(int x){
return 2*x;
}
可见,Lamdba表达式实际上是函数的简化,它由输入和输出组成
在JAVA中,实现Supplier<T>接口的对象,就是一个简化的函数,也就是一个Lambda表达式
Supplier<T>的源码
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
可以看到,这个接口的get方法不接收任何参数,返回一个泛型T
使用例子
public static <T> void show(String title,Stream<T> stream) {
final int size=10;
List<T> list=stream.limit(size).collect(Collectors.toList());
System.out.println(title+":");
for(int i=0;i<list.size();i++) {
if(i>0) System.out.print(",");
if(i<size) System.out.print(list.get(i));
else
System.out.print("...");
}
System.out.println();
}
main函数中:
Stream<String> stream3=Stream.generate(new Supplier<String>() {
public String get() {
return "return something";};
});
show("Supplier", stream3);
输出:
Supplier:
return something,return something,return something,return something,return something,return something,return something,return something,return something,return something
而一开始的例子
Stream<String> stream2=Stream.generate(()->"Echo");
show("echo", stream2);
也可以写成:
Stream<String> stream2=Stream.generate(new Supplier<String>() {
public String get() {
return "Echo";};
});
show("Supplier", stream2);
输出:
Supplier:
Echo,Echo,Echo,Echo,Echo,Echo,Echo,Echo,Echo,Echo
2、利用Stream.iterate(UnaryOperation <T> para)方法
该方法接收一个实现了UnaryOperation接口的方法
使用方法:
Stream<Integer> stream4=Stream.iterate(0,new UnaryOperator<Integer>() {
@Override
public Integer apply(Integer arg0) {
// TODO Auto-generated method stub
return arg0+1;
}
});
show("iterate", stream4);
输出:
iterate:
0,1,2,3,4,5,6,7,8,9
第一个参数类似种子,第二个方法指定了对初始值的具体操作,然后根据每次得到的值算出下一个值
指定种子0,操作为arg0+1
所以0,1,2,3,4,5,6...无限递增1;
获取无限流总结:
1、generate()方法通过反复地调用某一个函数构建无限流
2、iterate()方法通过指定种子,和变化函数(我就这么叫它吧哈哈)不断的获取下一个值来构建无限流