流的个人理解:
Stream也就是流,他和IO流不一样,他是java8诞生的东西,我对他的理解就是一个更为高级的容器,他可以轻易的对立面存储的数据进行各种各样的操作,比如过滤,转换,迭代等等。
流对集合,数组等进行了进一步的封装,使开发人员更容易的进行操作。
怎样获得流:
//List.stream
List<String> stringList = Lists.newArrayList();
Stream<String> stream = stringList.stream();
//Arrays.stream
String[] strings =
new
String[
2
];
Stream<String> stream1 = Arrays.stream(strings);
//基础类型流
IntStream intStream = IntStream.of(
1
,
2
,
3
);
LongStream longStream = LongStream.of(
1
,
2
,
3
);
DoubleStream doubleStream = DoubleStream.of(
1
,
2
,
3
);
//无限流
Stream.iterate(
0
, i -> i +
1
);
//当前值为上一个值+1,永无止境
Stream.generate(Math::random);
//每次获得的值是一个随机数,永无止境
这里提一句,这些方法的底层都是StreamSupport.stream(),他会把List,array封装为spliterator,具体细节可以观看源码。
|
怎样处理流:
中间操作和终端操作介绍:
如果把流看成是水源,水通过管道传输,管道中的各种阀门,可以看成是中间操作,比如过第一个阀门我给他限制排水量,第二个阀门,我往水里加可乐粉,当水离开管道后,把他放入水箱,
是终端操作,这个比喻可能不太恰当,下面写下比较官方的说法。
中间操作:诸如filter或sorted等中间操作会返回另一个流。这让多个操作可以连接起来形成一个查询。
终端操作:终端操作会从流的流水线生成结果。其结果是任何不是流的值,比如List、Integer,甚至void。
中间操作和终端操作的使用:
@Test
public
void
test(){
Stream<Person> stream = allPersonList.stream();
//只留下年龄大于25的人,中间操作
Stream<Person> personStream = stream.filter(person -> person.getAge() >
25
);
//将person流提取出name转换成String流,中间操作
Stream<String> personNameStream = personStream.map(Person::getName);
//将流收集起来转换成List,终端操作
List<String> nameList = personNameStream.collect(Collectors.toList());
System.out.println(nameList);
}
当然你可能会说这也太复杂了,我不用流也可以简单实现
@Test
public
void
test() {
List<String> nameList = Lists.newArrayList();
for
(Person person : allPersonList) {
if
(person.getAge() >
25
) {
nameList.add(person.getName());
}
}
System.out.println(nameList);
}
没错,这样做也很好的实现了,但是你看一下下面的代码
@Test
public
void
test() {
//筛选出年龄大于25的人的名字,是不是向读这句话一样简单的读完了这行代码
List<String> nameList = allPersonList.stream().filter(person -> person.getAge() >
25
).map(Person::getName).collect(Collectors.toList());
System.out.println(nameList);
}
|
这里还有提一点,Stream的操作属于懒加载,在终端操作执行前,所有的中间操作实际上都没有执行,他们每次都返回一个新的流并且把老的流存入他的成员变量里,这些中间操作形成了一个链表,在执行终端操作时,这些中间操作才会进行真正的操作。