Java函数式编程:三、流与函数式编程( 二 )

这样一个方法就是把我们的action方法执行n次,可以很好的替代普通的循环 。
generate() 方法
Stream.generate()方法可以接受一个方法作为参数 , 该方法必须要返回一个实例或基本类型 。总之 , 无论你给出的方法返回了什么,generate()方法会无限的根据该方法产生元素并塞入流中,如果你不希望它无限产生,那么你应该使用limit()来限制次数
AtomicInteger i = new AtomicInteger();Stream.generate(() -> i.getAndIncrement()).limit(20).forEach(System.out::println);// 输出为从0到19iterate()方法
顾名思义,这个方法通过迭代不断产生元素,它可以将第一个参数作为输入赋给第二个参数 (也就是那个方法),然后该方法会产生一个输出,随后该输出又会作为输入再度交给方法来产生下一个输出,由此不断迭代 。一个典型的例子是由此产生一个斐波那契数列的方法,如下所示 。
int x = 0;public Stream<Integer> numbers(){return Stream.iterate(1, o ->{int result = o + x;x = o;return result;});}public static void main(String[] args) {test2 t = new test2();t.numbers().limit(20).forEach(System.out::println);}流生成器
流生成器方法Stream.builder()可以返回Stream.Builder<T>类,你可以自定义这个返回的类的泛型以便适配需求,随后,你可以将它当作一个类似StringBuilder一样的存在使用,通过add()等方法向里面塞入元素,并最终通过build()方法来返回一个流 。
Stream.Builder<String> builder = Stream.builder();builder.add("a").add("b").add("c").build().map(x -> x.toUpperCase()).forEach(System.out::print);// 输出ABCArrays流方法
Arrays.stream()静态方法可以将一个数组转化为流,非常简单易理解
int[] chars = {1,2,3,4,5};Arrays.stream(chars).forEach(System.out::print);// 输出12345正则表达式
Java 8在java.util.regex.Pattern类中加入了一个新方法splitAsStream(),该方法接受一个字符序列并可以根据我们传入的公式将其分拆为一个流 。
要注意的是,这个地方的输入不能直接是一个流 , 必须得是一个CharSequence
String s = "abcdefg";Pattern.compile("[be]").splitAsStream(s).map(x -> x+"?").forEach(System.out::print);// 输出a?cd?fg?2、中间操作我们获取了流,那么我们要做什么呢?显然,我们希望逐个对流中的数据进行操作,我们有以下方式可?。?

  • 查看元素
    • peek()
  • 对元素排序
    • sorted()
    • sorted(Comparator compa)
  • 移除元素
    • distinct()
    • filter(Predicate)
  • 将函数应用于每个元素
    • map(Function func)
    • mapToInt(ToIntFunction func)
    • mapToLong(ToLongFunction func)
    • mapToDouble(ToDoubleFunction func)
  • 应用函数期间组合流
    • flatMap(Function func)
    • flatMapToInt(ToIntFunction func)
    • flatMapToLong(ToLongFunction func)
    • flatMapToDouble(ToDoubleFunction func)
查看元素
主要就是peek() , 它允许我们在不做任何操作的情况下查看流中的所有元素,其意义在于我们可以通过它来跟踪和调试我们的流代码,当你不知道你的代码中,这些流元素究竟被变成了什么样子的话,可以使用这个方法而不是forEach()来终止流 。
对元素排序
sorted()方法,同样很好理解,如果你不给Comparator作为参数,那么就是一个很普通的排序方法,类似Arrays.sort()这样,你可以查看源码来看看默认顺序究竟如何 。
不过更可靠的方法是我们自己来实现一个Comparator来操控整个流的比较结果 。
移除元素
主要有两种方法,分别是distinct()filter二者都很好用,distinct()可以消除那些重复的元素,这比通过Set来获取元素要便捷得多 。
filter(Predicate)更是全能,该方法需要以一个返回值为布尔的方法为变量,它会负责抛弃那些返回值为false的方法,留下那些返回值为true的方法,可以大大降低我们的代码量 。
将函数应用于各个元素
主要就是map(Function func),其他三个方法只是返回值变为对应的基本类型流而已,主要是为了提高效率 。我们需要提供一个能够处理流中元素并返回新值的方法,随后该方法就会将我们提供的参数方法应用于每个元素上 , 十分方便

推荐阅读