Java8 Stream类学习笔记

</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(1235);还有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);
	}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值