您的位置:首页 > 编程语言 > Java开发

Java8 Stream类学习笔记

2016-04-09 21:37 423 查看
</pre><p></p><pre name="code" class="java">今天看了一下午的Stream类,写点学习笔记,感觉还是理解不完全,应该还会有Stream类的后续笔记。


先贴一段采取Stream类实现的求一个String数组里所有质数的程序(请无视掉那个guava的com.google.common.collect.Lists的导入包):

import java.util.List;
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.Collectors;
import com.google.common.collect.Lists;

public class PrimeTest {
public static void main(String[] args){
int M;
Scanner in=new Scanner(System.in);
System.out.println("请输入数组大小:");
M=in.nextInt();
String[] a=new String[M];
System.out.println("请输入数字:");
for(int i=0;i<M;i++){
a[i]=in.next();
}
distinctPrimary(a);
}

public static void distinctPrimary(String... numbers) {
List<String> l = Arrays.asList(numbers);
List<Integer> r = l.stream()
.map(e -> new Integer(e))
.filter(e -> isPrime(e))
.distinct()
.collect(Collectors.toList());
System.out.println("distinctPrimary result is: " + r);
}

public static boolean isPrime(int number){
if(number==1){
return false;
}
for(int i=2;i<=Math.pow(number, 0.5);i++){
if(number%i==0&&number!=2){
return false;
}
}
return true;
}
}



代码是先指定数组大小,然后输入符合数组大小的一系列数字,结果是输出这些数字里所有不重复的素数。这里注意实现求素数算法可以直接用一个数循环除以不大于它的平方根的数字即可,不用从n-1开始除。具体原理为何我也不知道,这样的话复杂度会从O(n)变为O(sqrt(n)),据说还有复杂度更低的算法,以后有空再研究。

而主要的实现在distinctPrimary()方法里,该方法传进一个可变String参数(其实就是String数组,这个写法是在Java5里引入的,记得有面试题还问这种方法和传数组的方法的优劣比较,这个在以后再说)。传入的String数组转化为List后调用stream()方法生成流,然后调用流的map方法将String转化为Integer,再调用filter方法过滤掉那些不是素数的数,再调用distinct()方法去除重复数字,最后调用collect方法将结果收集到一个List里面。collect()方法接收一个collector类型的参数,该参数指明如何收集最终结果。

distinctPrimay()方法里主要用到了Java8的两大新特性,Lambda表达式和Stream流,Lambda表达式以后再说。主要说说Stream类,Stream是元素的集合,支持顺序和并行的对Stream进行汇聚的操作,有点类似于Iterator迭代器。它的创建方法主要有以下几种:一是使用Stream静态方法,包括of方法,如
Stream<Integer>
integerStream = Stream.of(
1
2
3
5
);还有generator方法和iterate方法,这两种方法生成的都是无限长度的,iterate方法生成是重复对给定的种子值调用用户指定函数,而generator方法是完全随机的,这两种方法一般要配合limit(int
n)方法。二是通过collection子类获取,程序就是采取的第二种方法。


Stream转换操作函数主要有distinct(),filter(),map()。以及reduce(),collect(),forEach(),toArray()等。前面的方法是Lazy的,后面的是eager的。在遇到eager方法前,Lazy方法并不会执行。遇到eager方法时前面的Lazy方法将以管道贯通的形式依次执行。也就是说每个元素依次通过这些方法管道,每调用中间方法一次会立刻返回一个新的Stream对象,前面的map,filter,distinct其实只执行了一次集合遍历而不是三次。另外Stream还有个parallelStream类变种,后者支持并行操作。


在本文就要结尾时又在网上发现了一个精简版的求素数程序,粘贴如下,写的真是6:



public static boolean isPrime(int number){
return number > 1 &&IntStream.rangeClosed(2, (int) Math.sqrt(number))
.noneMatch(divisor -> number % divisor == 0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: