ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java函数式编程

2022-11-07 12:26:31  阅读:273  来源: 互联网

标签:java 函数 学习 系统 语言 平台 方法 安装 QML c++ 数据


1、流的创建

最基本的流的创建方法就是

  • Stream.of(一组条目)
  • Collection.stream()

我们可以把任意相同类型的一组条目写在Stream.of()的参数中使之变成一个流,比如:

Stream.of("a", "b", "c", "d");
Stream.of(new Node(1), new Node(2), new Node(3));
Stream.of(1, 2, 3, 4, 5);

Collection接口的stream()方法则更是我们的好伙伴,所有实现了该接口的集合,都可以直接转变为一个流由我们处理。

此外,我们还有以下生成流的手段

  • 随机数流
  • int基本类型的区间范围方法
  • generate()方法
  • iterate()方法
  • 流生成器
  • Arrays.stream()将数组转换为流
  • 正则表达式

下面来逐一了解

随机数流

Random类已经得到了增强,现在有一组可以生成流的方法。

  • ints()
  • longs()
  • doubles()
  • boxed()

可以清楚的看到,我们只能通过Random类获取三种基本类型的流,或者在其后加上boxed()来获取它们的包装类的流。实际上,Random类生成的这些数值,还有别的价值,比如通过随机数来获取某个列表中的随机下表对应值,以此来获取随机的对象。

int区间范围方法

IntStraem类提供了新的range()方法,可以生成一个流,它代表一个由int值组成的序列,对于IntStream.range(a, b)来说,这个流中的数据是[a, b)区间的所有整数。

利用这个方法,我们可以通过流很好的代替某些循环了,比如:

public class Repeat{
    public static repeat(int n, Runnable action){
        IntStream.range(0, n).forEach(i -> action.run());
    }
}

这样一个方法就是把我们的action方法执行n次,可以很好的替代普通的循环。

generate() 方法

Stream.generate()方法可以接受一个方法作为参数,该方法必须要返回一个实例或基本类型。总之,无论你给出的方法返回了什么,generate()方法会无限的根据该方法产生元素并塞入流中,如果你不希望它无限产生,那么你应该使用limit()来限制次数

AtomicInteger i = new AtomicInteger();
Stream.generate(() -> i.getAndIncrement())
    .limit(20)
    .forEach(System.out::println);
// 输出为从0到19

iterate()方法

顾名思义,这个方法通过迭代不断产生元素,它可以将第一个参数作为输入赋给第二个参数 (也就是那个方法),然后该方法会产生一个输出,随后该输出又会作为输入再度交给方法来产生下一个输出,由此不断迭代。一个典型的例子是由此产生一个斐波那契数列的方法,如下所示。

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);
// 输出ABC

Arrays流方法

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)

标签:java,函数,学习,系统,语言,平台,方法,安装,QML,c++,数据
来源:

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有