java - java8中累积对的函数式方法

标签 java functional-programming java-8 java-stream

这是一些我试图将其转换为函数式编程代码的命令式代码:

public class Person {
    String name;
    Token token;

    public Person(String name, Token token) {
        this.name = name;
        this.token = token;
    }
}
public class Token {
    String id;
    boolean isValid;
    public Token(String id, boolean isValid) {
        this.id = id;
        this.isValid = isValid;
    }
    public String getId() { return id; }
    public boolean isValid() {return isValid;}
}
public static List<Token> getTokensForPerson(String name) {...}


public static List<Person> getPeople1 (String[] names) {

    List<Person> people = new ArrayList<Person> ();
    for (String name: names) {
        List<Token> tokens = getTokensForPerson(name);
        for (Token token: tokens) {
            if (token.isValid()) {
                people.add(new Person(name, token));
            }
        }

    }
    return people;
}

这是我尝试以函数式方式完成此操作。

public static List<Person> getPeople2 (String[] names) {

    return Arrays.stream(names).map(name -> getTokensForPerson(name))
        .flatMap(tokens -> tokens.stream().filter(token -> token.isValid))
        .map(token -> new Person(name, token))   // <== compiler error here. "Cannot resolve symbol 'name'"
        .collect(Collectors.toList());
}

但是它无法编译,因为在最后一个 map 操作中我需要引用 name 来创建 Person 对象,而 name 是那时不可用。有什么想法吗?

最佳答案

您可以在 flatMap 内移动 map 步骤:

return Arrays.stream(names)
        .<Person>flatMap(
                name -> getTokensForPerson(name).stream()
                        .filter(Token::isValid)
                        .map(token -> new Person(name, token)))
        .collect(Collectors.toList());

这样您也可以访问 name 变量。

StreamEx基于 -的解决方案更短,尽管它需要第三方库:

return StreamEx.of(names)
               .cross(name -> getTokensForPerson(name).stream())
               // Here we have the stream of entries 
               // where keys are names and values are tokens
               .filterValues(Token::isValid)
               .mapKeyValue(Person::new)
               .toList();

关于java - java8中累积对的函数式方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30808116/

相关文章:

javascript - 具有一流功能的语言是否一定允许闭包?

java - Java 8 中的顺序流在调用 collect 时是否使用组合器参数?

java - 创建引用父数组列表的方法

javascript - Nashorn 解析 TypeScript

java - 如何在 Oracle 中使用 Blob 对象作为 MapSqlParameterSource 的参数

functional-programming - 使用 Kotlin 将序列拆分为三个列表的惯用方法

java - Android 中特定时间段的调用阻止

java - 在流管道中保存到数据库

design-patterns - Java 默认接口(interface)方法具体用例

Java ObservableList 使用字符串谓词进行过滤