JAVASE8流库Stream学习总结(一)

什么是流
JAVASE8提供了一种叫做流的工具,他是一种在集合更高的概念级别的数据视图。在我看来,他是一种升级版的iterator(迭代器),但和
迭代器不同的是,流关注的是“做什么”,而不是“怎么做”。在集合的迭代器中,我们首先要获取迭代器,然后用迭代器对集合中的元素
进行遍历,顺便进行操作,而用流,我们只需要说明我们要干什么,而不是怎么去实现它
流的特点:
  1. 不存储任何元素
  2. 不改变数据源
  3. 惰性执行(意味着需要结果时才会执行某个操作)
流的工作流程:
  1. 流的建立
  2. 流的转换
  3. 流的聚合

下面重点记录流的使用
流的创建:
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()方法通过指定种子,和变化函数(我就这么叫它吧哈哈)不断的获取下一个值来构建无限流


posted @ 2018-06-11 14:48  小钟233  阅读(207)  评论(0编辑  收藏  举报